mirror of
https://github.com/nalgeon/redka.git
synced 2025-10-29 02:22:34 +08:00
postgres backend (#48)
This commit is contained in:
27
.github/workflows/build.yml
vendored
27
.github/workflows/build.yml
vendored
@@ -13,6 +13,20 @@ on:
|
||||
jobs:
|
||||
build:
|
||||
runs-on: ubuntu-latest
|
||||
services:
|
||||
postgres:
|
||||
image: postgres:17-alpine
|
||||
env:
|
||||
POSTGRES_USER: redka
|
||||
POSTGRES_PASSWORD: redka
|
||||
POSTGRES_DB: redka
|
||||
options: >-
|
||||
--health-cmd "pg_isready --username=redka --dbname=redka --quiet"
|
||||
--health-interval 10s
|
||||
--health-timeout 5s
|
||||
--health-retries 5
|
||||
ports:
|
||||
- 5432:5432
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v4
|
||||
@@ -20,7 +34,7 @@ jobs:
|
||||
- name: Setup Go
|
||||
uses: actions/setup-go@v5
|
||||
with:
|
||||
go-version: "stable"
|
||||
go-version-file: "go.mod"
|
||||
|
||||
- name: Install dependencies
|
||||
run: |
|
||||
@@ -28,8 +42,15 @@ jobs:
|
||||
sudo apt-get install -y libsqlite3-dev
|
||||
go get .
|
||||
|
||||
- name: Test and build
|
||||
run: make test build
|
||||
- name: Install linter
|
||||
uses: golangci/golangci-lint-action@v8
|
||||
|
||||
- name: Build and test
|
||||
run: |
|
||||
make build
|
||||
make vet lint
|
||||
make test-sqlite
|
||||
make test-postgres
|
||||
|
||||
- name: Upload artifact
|
||||
uses: actions/upload-artifact@v4
|
||||
|
||||
2
.github/workflows/docker.yml
vendored
2
.github/workflows/docker.yml
vendored
@@ -3,7 +3,7 @@ name: docker
|
||||
on:
|
||||
push:
|
||||
tags:
|
||||
- "*"
|
||||
- "v*.*.*"
|
||||
workflow_dispatch:
|
||||
|
||||
jobs:
|
||||
|
||||
5
.github/workflows/publish.yml
vendored
5
.github/workflows/publish.yml
vendored
@@ -3,7 +3,7 @@ name: publish
|
||||
on:
|
||||
push:
|
||||
tags:
|
||||
- "*"
|
||||
- "v*.*.*"
|
||||
workflow_dispatch:
|
||||
|
||||
permissions:
|
||||
@@ -33,7 +33,7 @@ jobs:
|
||||
- name: Set up Go
|
||||
uses: actions/setup-go@v5
|
||||
with:
|
||||
go-version: "stable"
|
||||
go-version-file: "go.mod"
|
||||
|
||||
- name: Build binary
|
||||
run: GOOS=${{ matrix.goos }} make build
|
||||
@@ -85,3 +85,4 @@ jobs:
|
||||
file: release/*
|
||||
file_glob: true
|
||||
tag: ${{ github.ref }}
|
||||
draft: true
|
||||
|
||||
49
Makefile
49
Makefile
@@ -1,4 +1,4 @@
|
||||
.PHONY: setup lint vet test build run
|
||||
.PHONY: build
|
||||
|
||||
has_git := $(shell command -v git 2>/dev/null)
|
||||
|
||||
@@ -20,21 +20,60 @@ build_date := $(shell date -u '+%Y-%m-%dT%H:%M:%S')
|
||||
setup:
|
||||
@go mod download
|
||||
|
||||
lint:
|
||||
@golangci-lint run --print-issued-lines=false --out-format=colored-line-number ./...
|
||||
|
||||
vet:
|
||||
@echo "> running vet..."
|
||||
@go vet ./...
|
||||
@echo "✓ finished vet"
|
||||
|
||||
lint:
|
||||
@echo "> running lint..."
|
||||
@golangci-lint run ./...
|
||||
@echo "✓ finished lint"
|
||||
|
||||
test:
|
||||
@go test ./... -v
|
||||
@echo "> running tests with $(driver) driver..."
|
||||
@go test -tags=$(driver) ./...
|
||||
@echo "✓ finished tests"
|
||||
|
||||
test-sqlite:
|
||||
@echo "> running tests with sqlite driver..."
|
||||
@go test -tags=sqlite3 ./...
|
||||
@echo "✓ finished tests"
|
||||
|
||||
test-postgres:
|
||||
@echo "> running tests with postgres driver..."
|
||||
@go test -tags=postgres -p=1 ./...
|
||||
@echo "✓ finished tests"
|
||||
|
||||
build:
|
||||
@echo "> running build..."
|
||||
@CGO_ENABLED=1 go build -ldflags "-s -w -X main.version=$(build_ver) -X main.commit=$(build_rev) -X main.date=$(build_date)" -trimpath -o build/redka -v cmd/redka/main.go
|
||||
@echo "✓ finished build"
|
||||
|
||||
build-cli:
|
||||
@CGO_ENABLED=1 go build -ldflags "-s -w" -trimpath -o build/redka-cli -v cmd/cli/main.go
|
||||
|
||||
run:
|
||||
@./build/redka
|
||||
|
||||
postgres-start:
|
||||
@echo "> starting postgres..."
|
||||
@docker run --rm --detach --name=redka-postgres \
|
||||
--env=POSTGRES_DB=redka \
|
||||
--env=POSTGRES_USER=redka \
|
||||
--env=POSTGRES_PASSWORD=redka \
|
||||
--publish=5432:5432 \
|
||||
--tmpfs /var/lib/postgresql/data \
|
||||
postgres:17-alpine
|
||||
@until docker exec redka-postgres \
|
||||
pg_isready --username=redka --dbname=redka --quiet --quiet; \
|
||||
do sleep 1; done
|
||||
@echo "✓ started postgres"
|
||||
|
||||
postgres-stop:
|
||||
@echo "> stopping postgres..."
|
||||
@docker stop redka-postgres
|
||||
@echo "✓ stopped postgres"
|
||||
|
||||
postgres-shell:
|
||||
@docker exec -it redka-postgres psql --username=redka --dbname=redka
|
||||
33
README.md
33
README.md
@@ -1,17 +1,28 @@
|
||||
<img alt="Redka" src="logo.svg" height="80" align="center">
|
||||
|
||||
Redka aims to reimplement the core parts of Redis with SQLite, while remaining compatible with Redis API.
|
||||
Redka aims to reimplement the core parts of Redis with SQL, while remaining compatible with Redis API.
|
||||
|
||||
Notable features:
|
||||
|
||||
- Data does not have to fit in RAM.
|
||||
- ACID transactions.
|
||||
- SQL views for better introspection and reporting.
|
||||
- Both in-process (Go API) and standalone (RESP) servers.
|
||||
- Redis-compatible commands and wire protocol.
|
||||
- Data doesn't have to fit in RAM.
|
||||
- Supports ACID transactions.
|
||||
- SQL views for easier analysis and reporting.
|
||||
- Works with both SQLite and PostgreSQL (coming v0.6.0) backends.
|
||||
- Runs in-process (Go API) or as a standalone server.
|
||||
- Redis-compatible commands and wire protocol (RESP).
|
||||
|
||||
Redka is [functionally ready](docs/roadmap.md) for 1.0. Feel free to try it in non-critical production scenarios and provide feedback in the issues.
|
||||
|
||||
## Use cases
|
||||
|
||||
Here are some situations where Redka might be helpful:
|
||||
|
||||
_Embedded cache for Go applications_. If your Go app already uses SQLite or just needs a simple, built-in key-value store, Redka is a natural fit. It gives you Redis-like features without the hassle of running a separate server. The cache persists across application restarts, and backup is as easy as copying a file.
|
||||
|
||||
_Lightweight testing environment_. Your app uses Redis in production, but setting up a Redis server for local development or integration tests can be a hassle. Redka, when used with an in-memory SQLite database, gives you a fast alternative with complete isolation for each test run.
|
||||
|
||||
_Postgres-first data structures_. If you prefer to use PostgreSQL for everything but need Redis-like data structures (like lists and sorted sets), Redka can use your existing database as the backend. This way, you can manage both relational data and specialized data structures with the same tools and transactional guarantees.
|
||||
|
||||
## Commands
|
||||
|
||||
Redka supports five core Redis data types:
|
||||
@@ -31,17 +42,21 @@ Redka comes in two flavors:
|
||||
- Standalone Redis-compatible server: [installation](docs/install-standalone.md), [usage](docs/usage-standalone.md).
|
||||
- Go module for in-process use: [installation](docs/install-module.md), [usage](docs/usage-module.md).
|
||||
|
||||
## Storage
|
||||
|
||||
Redka can use either SQLite or PostgreSQL as its backend. It stores data in a [SQL database](docs/persistence.md) with a simple schema and provides views for better introspection.
|
||||
|
||||
## Performance
|
||||
|
||||
According to the [benchmarks](docs/performance.md), Redka is several times slower than Redis. Still, it can do up to 100K op/sec on a Macbook Air, which is pretty good if you ask me (and probably 10x more than most applications will ever need).
|
||||
Redka is not about raw performance. You can't beat a specialized data store like Redis with a general-purpose relational backend like SQLite. However, Redka can still handle tens of thousands of operations per second, which should be more than enough for many apps.
|
||||
|
||||
Redka stores data in a [SQLite database](docs/persistence.md) with a simple schema and provides views for better introspection.
|
||||
See the [benchmarks](docs/performance.md) for more details.
|
||||
|
||||
## Contributing
|
||||
|
||||
Contributions are welcome. For anything other than bugfixes, please first open an issue to discuss what you want to change.
|
||||
|
||||
Be sure to add or update tests as appropriate.
|
||||
Make sure to add or update tests as needed.
|
||||
|
||||
## Acknowledgements
|
||||
|
||||
|
||||
@@ -17,7 +17,7 @@ const dbURI = "file:/data.db?vfs=memdb"
|
||||
|
||||
func init() {
|
||||
flag.Usage = func() {
|
||||
fmt.Fprintf(flag.CommandLine.Output(), "Usage: redka-cli <filename>\n")
|
||||
_, _ = fmt.Fprintf(flag.CommandLine.Output(), "Usage: redka-cli <filename>\n")
|
||||
flag.PrintDefaults()
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,24 +1,29 @@
|
||||
// Redka server.
|
||||
// Example usage:
|
||||
//
|
||||
// Example usage (SQLite):
|
||||
//
|
||||
// ./redka -h localhost -p 6379 redka.db
|
||||
//
|
||||
// Example usage (client):
|
||||
// Example usage (PostgreSQL):
|
||||
//
|
||||
// docker run --rm -it redis redis-cli -h host.docker.internal -p 6379
|
||||
// ./redka -h localhost -p 6379 "postgres://redka:redka@localhost:5432/redka?sslmode=disable"
|
||||
package main
|
||||
|
||||
import (
|
||||
"cmp"
|
||||
"context"
|
||||
"database/sql"
|
||||
"flag"
|
||||
"fmt"
|
||||
"log/slog"
|
||||
"net"
|
||||
"net/url"
|
||||
"os"
|
||||
"os/signal"
|
||||
"strings"
|
||||
"syscall"
|
||||
|
||||
_ "github.com/lib/pq"
|
||||
"github.com/mattn/go-sqlite3"
|
||||
"github.com/nalgeon/redka"
|
||||
"github.com/nalgeon/redka/internal/server"
|
||||
@@ -31,9 +36,10 @@ var (
|
||||
date = "unknown"
|
||||
)
|
||||
|
||||
const driverName = "redka"
|
||||
const memoryURI = "file:/data.db?vfs=memdb"
|
||||
const pragma = `
|
||||
const debugPort = 6060
|
||||
const sqliteDriverName = "sqlite-redka"
|
||||
const sqliteMemoryURI = "file:/redka.db?vfs=memdb"
|
||||
const sqlitePragma = `
|
||||
pragma journal_mode = wal;
|
||||
pragma synchronous = normal;
|
||||
pragma temp_store = memory;
|
||||
@@ -53,100 +59,41 @@ func (c *Config) Addr() string {
|
||||
return net.JoinHostPort(c.Host, c.Port)
|
||||
}
|
||||
|
||||
var config Config
|
||||
|
||||
func init() {
|
||||
// Set up command line flags.
|
||||
// Set up flag usage message.
|
||||
flag.Usage = func() {
|
||||
fmt.Fprintf(flag.CommandLine.Output(), "Usage: redka [options] <data-source>\n")
|
||||
_, _ = fmt.Fprintf(flag.CommandLine.Output(), "Usage: redka [options] <data-source>\n")
|
||||
flag.PrintDefaults()
|
||||
}
|
||||
flag.StringVar(&config.Host, "h", "localhost", "server host")
|
||||
flag.StringVar(&config.Port, "p", "6379", "server port")
|
||||
flag.StringVar(&config.Sock, "s", "", "server socket (overrides host and port)")
|
||||
flag.BoolVar(&config.Verbose, "v", false, "verbose logging")
|
||||
|
||||
// Register an SQLite driver with custom pragmas.
|
||||
// Ensures that the PRAGMA settings apply to
|
||||
// all connections opened by the driver.
|
||||
sql.Register(driverName, &sqlite3.SQLiteDriver{
|
||||
sql.Register(sqliteDriverName, &sqlite3.SQLiteDriver{
|
||||
ConnectHook: func(conn *sqlite3.SQLiteConn) error {
|
||||
_, err := conn.Exec(pragma, nil)
|
||||
_, err := conn.Exec(sqlitePragma, nil)
|
||||
return err
|
||||
},
|
||||
})
|
||||
}
|
||||
|
||||
func main() {
|
||||
// Parse command line arguments.
|
||||
flag.Parse()
|
||||
if len(flag.Args()) > 1 {
|
||||
flag.Usage()
|
||||
os.Exit(1)
|
||||
}
|
||||
config := mustReadConfig()
|
||||
logger := setupLogger(config)
|
||||
|
||||
// Set the data source.
|
||||
if len(flag.Args()) == 0 {
|
||||
config.Path = memoryURI
|
||||
} else {
|
||||
config.Path = flag.Arg(0)
|
||||
}
|
||||
slog.Info("starting redka", "version", version, "commit", commit, "built_at", date)
|
||||
|
||||
// Prepare a context to handle shutdown signals.
|
||||
ctx, stop := signal.NotifyContext(context.Background(), os.Interrupt, syscall.SIGTERM)
|
||||
defer stop()
|
||||
|
||||
// Set up logging.
|
||||
logLevel := new(slog.LevelVar)
|
||||
logHandler := slog.NewTextHandler(os.Stdout, &slog.HandlerOptions{Level: logLevel})
|
||||
logger := slog.New(logHandler)
|
||||
slog.SetDefault(logger)
|
||||
if config.Verbose {
|
||||
logLevel.Set(slog.LevelDebug)
|
||||
}
|
||||
|
||||
// Print version information.
|
||||
slog.Info("starting redka", "version", version, "commit", commit, "built_at", date)
|
||||
|
||||
// Open the database.
|
||||
opts := redka.Options{
|
||||
DriverName: driverName,
|
||||
Logger: logger,
|
||||
Pragma: map[string]string{},
|
||||
}
|
||||
db, err := redka.Open(config.Path, &opts)
|
||||
if err != nil {
|
||||
slog.Error("data source", "error", err)
|
||||
os.Exit(1)
|
||||
}
|
||||
slog.Info("data source", "path", config.Path)
|
||||
db := mustOpenDB(config, logger)
|
||||
|
||||
// Create the server.
|
||||
var srv *server.Server
|
||||
if config.Sock != "" {
|
||||
srv = server.New("unix", config.Sock, db)
|
||||
} else {
|
||||
srv = server.New("tcp", config.Addr(), db)
|
||||
}
|
||||
|
||||
// Start the server.
|
||||
var errCh = make(chan error, 1)
|
||||
go func() {
|
||||
if err := srv.Start(); err != nil {
|
||||
errCh <- fmt.Errorf("start server: %w", err)
|
||||
}
|
||||
}()
|
||||
|
||||
// Start the debug server.
|
||||
var debugSrv *server.DebugServer
|
||||
if config.Verbose {
|
||||
debugSrv = server.NewDebug("localhost", 6060)
|
||||
go func() {
|
||||
if err := debugSrv.Start(); err != nil {
|
||||
errCh <- fmt.Errorf("start debug server: %w", err)
|
||||
}
|
||||
}()
|
||||
}
|
||||
// Start application and debug servers.
|
||||
errCh := make(chan error, 1)
|
||||
srv := startServer(config, db, errCh)
|
||||
debugSrv := startDebugServer(config, errCh)
|
||||
|
||||
// Wait for a shutdown signal or a startup error.
|
||||
select {
|
||||
@@ -159,6 +106,120 @@ func main() {
|
||||
}
|
||||
}
|
||||
|
||||
// mustReadConfig reads the configuration from
|
||||
// command line arguments and environment variables.
|
||||
func mustReadConfig() Config {
|
||||
if len(flag.Args()) > 1 {
|
||||
flag.Usage()
|
||||
os.Exit(1)
|
||||
}
|
||||
|
||||
var config Config
|
||||
flag.StringVar(
|
||||
&config.Host, "h",
|
||||
cmp.Or(os.Getenv("REDKA_HOST"), "localhost"),
|
||||
"server host",
|
||||
)
|
||||
flag.StringVar(
|
||||
&config.Port, "p",
|
||||
cmp.Or(os.Getenv("REDKA_PORT"), "6379"),
|
||||
"server port",
|
||||
)
|
||||
flag.StringVar(
|
||||
&config.Sock, "s",
|
||||
cmp.Or(os.Getenv("REDKA_SOCK"), ""),
|
||||
"server socket (overrides host and port)",
|
||||
)
|
||||
flag.BoolVar(&config.Verbose, "v", false, "verbose logging")
|
||||
flag.Parse()
|
||||
|
||||
config.Path = cmp.Or(flag.Arg(0), os.Getenv("REDKA_DB_URL"), sqliteMemoryURI)
|
||||
return config
|
||||
}
|
||||
|
||||
// setupLogger setups a logger for the application.
|
||||
func setupLogger(config Config) *slog.Logger {
|
||||
logLevel := new(slog.LevelVar)
|
||||
logHandler := slog.NewTextHandler(os.Stdout, &slog.HandlerOptions{Level: logLevel})
|
||||
logger := slog.New(logHandler)
|
||||
slog.SetDefault(logger)
|
||||
if config.Verbose {
|
||||
logLevel.Set(slog.LevelDebug)
|
||||
}
|
||||
return logger
|
||||
}
|
||||
|
||||
// mustOpenDB connects to the database.
|
||||
func mustOpenDB(config Config, logger *slog.Logger) *redka.DB {
|
||||
// Connect to the database using the inferred driver.
|
||||
driverName := inferDriverName(config.Path)
|
||||
opts := redka.Options{
|
||||
DriverName: driverName,
|
||||
Logger: logger,
|
||||
// Using nil for pragma sets the default options.
|
||||
// We don't want any options, so pass an empty map instead.
|
||||
Pragma: map[string]string{},
|
||||
}
|
||||
db, err := redka.Open(config.Path, &opts)
|
||||
if err != nil {
|
||||
slog.Error("data source", "error", err)
|
||||
os.Exit(1)
|
||||
}
|
||||
|
||||
// Hide password when logging.
|
||||
maskedPath := config.Path
|
||||
if u, err := url.Parse(maskedPath); err == nil && u.User != nil {
|
||||
u.User = url.User(u.User.Username())
|
||||
maskedPath = u.String()
|
||||
}
|
||||
slog.Info("data source", "driver", driverName, "path", maskedPath)
|
||||
|
||||
return db
|
||||
}
|
||||
|
||||
// inferDriverName infers the driver name from the data source URI.
|
||||
func inferDriverName(path string) string {
|
||||
// Infer the driver name based on the data source URI.
|
||||
if strings.HasPrefix(path, "postgres://") {
|
||||
return "postgres"
|
||||
}
|
||||
return sqliteDriverName
|
||||
}
|
||||
|
||||
// startServer starts the application server.
|
||||
func startServer(config Config, db *redka.DB, errCh chan<- error) *server.Server {
|
||||
// Create the server.
|
||||
var srv *server.Server
|
||||
if config.Sock != "" {
|
||||
srv = server.New("unix", config.Sock, db)
|
||||
} else {
|
||||
srv = server.New("tcp", config.Addr(), db)
|
||||
}
|
||||
|
||||
// Start the server.
|
||||
go func() {
|
||||
if err := srv.Start(); err != nil {
|
||||
errCh <- fmt.Errorf("start server: %w", err)
|
||||
}
|
||||
}()
|
||||
|
||||
return srv
|
||||
}
|
||||
|
||||
// startDebugServer starts the debug server.
|
||||
func startDebugServer(config Config, errCh chan<- error) *server.DebugServer {
|
||||
if !config.Verbose {
|
||||
return nil
|
||||
}
|
||||
srv := server.NewDebug("localhost", debugPort)
|
||||
go func() {
|
||||
if err := srv.Start(); err != nil {
|
||||
errCh <- fmt.Errorf("start debug server: %w", err)
|
||||
}
|
||||
}()
|
||||
return srv
|
||||
}
|
||||
|
||||
// shutdown stops the main server and the debug server.
|
||||
func shutdown(srv *server.Server, debugSrv *server.DebugServer) {
|
||||
// Stop the debug server.
|
||||
|
||||
@@ -6,12 +6,18 @@ Install the module as follows:
|
||||
go get github.com/nalgeon/redka
|
||||
```
|
||||
|
||||
You'll also need an SQLite driver. Use one of the following:
|
||||
You'll also need an SQLite or PostgreSQL driver.
|
||||
|
||||
Use one of the following for SQLite:
|
||||
|
||||
- `github.com/mattn/go-sqlite3` (CGO, fastest)
|
||||
- `github.com/ncruces/go-sqlite3` (pure Go, WASM)
|
||||
- `github.com/tursodatabase/go-libsql` (CGO)
|
||||
- `modernc.org/sqlite` (pure Go)
|
||||
- `modernc.org/sqlite` (pure Go, libc port)
|
||||
|
||||
Or one of the following for PostgreSQL:
|
||||
|
||||
- `github.com/lib/pq`
|
||||
- `github.com/jackc/pgx/v5`
|
||||
|
||||
Install a driver with `go get` like this:
|
||||
|
||||
|
||||
@@ -7,21 +7,11 @@ I've compared Redka with Redis using [redis-benchmark](https://redis.io/docs/man
|
||||
- 10000 randomized keys
|
||||
- GET/SET commands
|
||||
|
||||
SQLite settings:
|
||||
|
||||
```
|
||||
pragma journal_mode = wal;
|
||||
pragma synchronous = normal;
|
||||
pragma temp_store = memory;
|
||||
pragma mmap_size = 268435456;
|
||||
pragma foreign_keys = on;
|
||||
```
|
||||
|
||||
Hardware: Apple M1 8-core CPU, 16GB RAM
|
||||
## Results
|
||||
|
||||
Redis:
|
||||
|
||||
```
|
||||
```text
|
||||
redis-server --appendonly no
|
||||
redis-benchmark -p 6379 -q -c 10 -n 1000000 -r 10000 -t get,set
|
||||
|
||||
@@ -29,9 +19,9 @@ SET: 133262.25 requests per second, p50=0.055 msec
|
||||
GET: 139217.59 requests per second, p50=0.055 msec
|
||||
```
|
||||
|
||||
Redka (in-memory):
|
||||
Redka (SQLite, in-memory):
|
||||
|
||||
```
|
||||
```text
|
||||
./redka -p 6380
|
||||
redis-benchmark -p 6380 -q -c 10 -n 1000000 -r 10000 -t get,set
|
||||
|
||||
@@ -39,14 +29,50 @@ SET: 36188.62 requests per second, p50=0.167 msec
|
||||
GET: 104405.93 requests per second, p50=0.063 msec
|
||||
```
|
||||
|
||||
Redka (persisted to disk):
|
||||
Redka (SQLite, persisted to disk):
|
||||
|
||||
```
|
||||
./redka -p 6380 data.db
|
||||
```text
|
||||
./redka -p 6380 redka.db
|
||||
redis-benchmark -p 6380 -q -c 10 -n 1000000 -r 10000 -t get,set
|
||||
|
||||
SET: 26773.76 requests per second, p50=0.215 msec
|
||||
GET: 103092.78 requests per second, p50=0.063 msec
|
||||
```
|
||||
|
||||
So while Redka is 2-5 times slower than Redis (not surprising, since we are comparing a relational database to a key-value data store), it can still do 26K writes/sec and 94K reads/sec, which is pretty good if you ask me.
|
||||
Redka (PostgreSQL):
|
||||
|
||||
```text
|
||||
./redka -p 6380 "postgres://redka:redka@localhost:5432/redka?sslmode=disable"
|
||||
redis-benchmark -p 6380 -q -c 10 -n 100000 -r 10000 -t get,set
|
||||
|
||||
SET: 11941.72 requests per second, p50=0.775 msec
|
||||
GET: 25766.55 requests per second, p50=0.359 msec
|
||||
```
|
||||
|
||||
So while Redka is noticeably slower than Redis (not surprising, since we are comparing a relational database to a key-value data store), it can still handle tens of thousands of operations per second. That should be more than enough for many apps.
|
||||
|
||||
## Environment
|
||||
|
||||
Hardware: Apple M1 8-core CPU, 16GB RAM
|
||||
|
||||
SQLite settings:
|
||||
|
||||
```text
|
||||
pragma journal_mode = wal;
|
||||
pragma synchronous = normal;
|
||||
pragma temp_store = memory;
|
||||
pragma mmap_size = 268435456;
|
||||
pragma foreign_keys = on;
|
||||
```
|
||||
|
||||
PostgreSQL settings:
|
||||
|
||||
```text
|
||||
checkpoint_completion_target=0.9
|
||||
effective_cache_size=4GB
|
||||
maintenance_work_mem=512MB
|
||||
max_wal_size=1GB
|
||||
random_page_cost=1.1
|
||||
shared_buffers=1GB
|
||||
wal_buffers=16MB
|
||||
```
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
# Persistence
|
||||
|
||||
Redka stores data in a SQLite database using the following tables:
|
||||
Redka stores data in a SQL database using the following tables:
|
||||
|
||||
```
|
||||
rkey
|
||||
|
||||
@@ -47,19 +47,19 @@ After opening the database, call `redka.DB` methods to run individual commands:
|
||||
db.Str().Set("name", "alice")
|
||||
db.Str().Set("age", 25)
|
||||
|
||||
count, err := db.Key().Count("name", "age", "city")
|
||||
slog.Info("count", "count", count, "err", err)
|
||||
|
||||
name, err := db.Str().Get("name")
|
||||
slog.Info("get", "name", name, "err", err)
|
||||
|
||||
age, err := db.Str().Get("age")
|
||||
slog.Info("get", "age", age, "err", err)
|
||||
```
|
||||
|
||||
```
|
||||
count count=2 err=<nil>
|
||||
```text
|
||||
get name="alice" err=<nil>
|
||||
get age="25" err=<nil>
|
||||
```
|
||||
|
||||
See the full example in [example/simple/main.go](../example/simple/main.go).
|
||||
See the full example in [example/mattn/main.go](../example/mattn/main.go).
|
||||
|
||||
## Transactions
|
||||
|
||||
@@ -84,7 +84,7 @@ err := db.Update(func(tx *redka.Tx) error {
|
||||
slog.Info("updated", "count", updCount, "err", err)
|
||||
```
|
||||
|
||||
```
|
||||
```text
|
||||
updated count=2 err=<nil>
|
||||
```
|
||||
|
||||
@@ -94,7 +94,11 @@ See the full example in [example/tx/main.go](../example/tx/main.go).
|
||||
|
||||
Redka supports the following SQLite drivers:
|
||||
|
||||
- `github.com/mattn/go-sqlite3` ([example](../example/simple/main.go))
|
||||
- `github.com/mattn/go-sqlite3` ([example](../example/mattn/main.go))
|
||||
- `github.com/ncruces/go-sqlite3` ([example](../example/ncruces/main.go))
|
||||
- `github.com/tursodatabase/go-libsql` ([example](../example/libsql/main.go))
|
||||
- `modernc.org/sqlite` ([example](../example/modernc/main.go))
|
||||
|
||||
And the following Postgres drivers:
|
||||
|
||||
- `github.com/lib/pq` ([example](../example/postgres/main.go))
|
||||
- `github.com/jackc/pgx/v5`
|
||||
|
||||
@@ -9,10 +9,20 @@ redka [-h host] [-p port] [-s unix-socket] [db-path]
|
||||
For example:
|
||||
|
||||
```shell
|
||||
# use in-memory sqlite database
|
||||
./redka
|
||||
|
||||
# use file sqlite database
|
||||
./redka data.db
|
||||
|
||||
# listen on all network interfaces
|
||||
./redka -h 0.0.0.0 -p 6379 data.db
|
||||
|
||||
# listen on unix socket
|
||||
./redka -s /tmp/redka.sock data.db
|
||||
|
||||
# use postgres database
|
||||
./redka -p 6379 "postgres://redka:redka@localhost:5432/redka?sslmode=disable"
|
||||
```
|
||||
|
||||
Server defaults are host `localhost`, port `6379` and empty DB path. The unix socket path, if given, overrides the host/port arguments.
|
||||
@@ -42,7 +52,7 @@ Once the server is running, connect to it using `redis-cli` or an API client lik
|
||||
redis-cli -h localhost -p 6379
|
||||
```
|
||||
|
||||
```
|
||||
```text
|
||||
127.0.0.1:6379> echo hello
|
||||
"hello"
|
||||
127.0.0.1:6379> set name alice
|
||||
|
||||
@@ -2,29 +2,29 @@ module github.com/nalgeon/redka/example
|
||||
|
||||
replace github.com/nalgeon/redka => ../
|
||||
|
||||
go 1.22
|
||||
go 1.23.0
|
||||
|
||||
toolchain go1.24.0
|
||||
|
||||
require (
|
||||
github.com/mattn/go-sqlite3 v1.14.22
|
||||
github.com/lib/pq v1.10.9
|
||||
github.com/mattn/go-sqlite3 v1.14.28
|
||||
github.com/nalgeon/redka v0.0.0-00010101000000-000000000000
|
||||
github.com/ncruces/go-sqlite3 v0.16.2
|
||||
github.com/tursodatabase/go-libsql v0.0.0-20240429120401-651096bbee0b
|
||||
modernc.org/sqlite v1.29.5
|
||||
)
|
||||
|
||||
require (
|
||||
github.com/antlr4-go/antlr/v4 v4.13.0 // indirect
|
||||
github.com/dustin/go-humanize v1.0.1 // indirect
|
||||
github.com/google/uuid v1.3.0 // indirect
|
||||
github.com/hashicorp/golang-lru/v2 v2.0.7 // indirect
|
||||
github.com/libsql/sqlite-antlr4-parser v0.0.0-20240327125255-dbf53b6cbf06 // indirect
|
||||
github.com/mattn/go-isatty v0.0.16 // indirect
|
||||
github.com/ncruces/go-strftime v0.1.9 // indirect
|
||||
github.com/ncruces/julianday v1.0.0 // indirect
|
||||
github.com/remyoudompheng/bigfft v0.0.0-20230129092748-24d4a6f8daec // indirect
|
||||
github.com/tetratelabs/wazero v1.7.3 // indirect
|
||||
golang.org/x/exp v0.0.0-20240325151524-a685a6edb6d8 // indirect
|
||||
golang.org/x/sys v0.21.0 // indirect
|
||||
golang.org/x/tools v0.19.0 // indirect
|
||||
modernc.org/gc/v3 v3.0.0-20240107210532-573471604cb6 // indirect
|
||||
modernc.org/libc v1.41.0 // indirect
|
||||
modernc.org/mathutil v1.6.0 // indirect
|
||||
|
||||
@@ -1,47 +1,33 @@
|
||||
github.com/antlr4-go/antlr/v4 v4.13.0 h1:lxCg3LAv+EUK6t1i0y1V6/SLeUi0eKEKdhQAlS8TVTI=
|
||||
github.com/antlr4-go/antlr/v4 v4.13.0/go.mod h1:pfChB/xh/Unjila75QW7+VU4TSnWnnk9UTnmpPaOR2g=
|
||||
github.com/dustin/go-humanize v1.0.1 h1:GzkhY7T5VNhEkwH0PVJgjz+fX1rhBrR7pRT3mDkpeCY=
|
||||
github.com/dustin/go-humanize v1.0.1/go.mod h1:Mu1zIs6XwVuF/gI1OepvI0qD18qycQx+mFykh5fBlto=
|
||||
github.com/google/go-cmp v0.5.9 h1:O2Tfq5qg4qc4AmwVlvv0oLiVAGB7enBSJ2x2DqQFi38=
|
||||
github.com/google/go-cmp v0.5.9/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
|
||||
github.com/google/pprof v0.0.0-20221118152302-e6195bd50e26 h1:Xim43kblpZXfIBQsbuBVKCudVG457BR2GZFIz3uw3hQ=
|
||||
github.com/google/pprof v0.0.0-20221118152302-e6195bd50e26/go.mod h1:dDKJzRmX4S37WGHujM7tX//fmj1uioxKzKxz3lo4HJo=
|
||||
github.com/google/uuid v1.3.0 h1:t6JiXgmwXMjEs8VusXIJk2BXHsn+wx8BZdTaoZ5fu7I=
|
||||
github.com/google/uuid v1.3.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
|
||||
github.com/hashicorp/golang-lru/v2 v2.0.7 h1:a+bsQ5rvGLjzHuww6tVxozPZFVghXaHOwFs4luLUK2k=
|
||||
github.com/hashicorp/golang-lru/v2 v2.0.7/go.mod h1:QeFd9opnmA6QUJc5vARoKUSoFhyfM2/ZepoAG6RGpeM=
|
||||
github.com/libsql/sqlite-antlr4-parser v0.0.0-20240327125255-dbf53b6cbf06 h1:JLvn7D+wXjH9g4Jsjo+VqmzTUpl/LX7vfr6VOfSWTdM=
|
||||
github.com/libsql/sqlite-antlr4-parser v0.0.0-20240327125255-dbf53b6cbf06/go.mod h1:FUkZ5OHjlGPjnM2UyGJz9TypXQFgYqw6AFNO1UiROTM=
|
||||
github.com/lib/pq v1.10.9 h1:YXG7RB+JIjhP29X+OtkiDnYaXQwpS4JEWq7dtCCRUEw=
|
||||
github.com/lib/pq v1.10.9/go.mod h1:AlVN5x4E4T544tWzH6hKfbfQvm3HdbOxrmggDNAPY9o=
|
||||
github.com/mattn/go-isatty v0.0.16 h1:bq3VjFmv/sOjHtdEhmkEV4x1AJtvUvOJ2PFAZ5+peKQ=
|
||||
github.com/mattn/go-isatty v0.0.16/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM=
|
||||
github.com/mattn/go-sqlite3 v1.14.22 h1:2gZY6PC6kBnID23Tichd1K+Z0oS6nE/XwU+Vz/5o4kU=
|
||||
github.com/mattn/go-sqlite3 v1.14.22/go.mod h1:Uh1q+B4BYcTPb+yiD3kU8Ct7aC0hY9fxUwlHK0RXw+Y=
|
||||
github.com/ncruces/go-sqlite3 v0.16.2-0.20240609232415-e7f8311e2e0d h1:pq4oCRorhPT5EFOyw7OFkGXtJHJ/ViMDjBSmJlPV61g=
|
||||
github.com/ncruces/go-sqlite3 v0.16.2-0.20240609232415-e7f8311e2e0d/go.mod h1:feFXbBcbLtxNk6XWG1ROt8MS9+E45yCW3G8o4ixIqZ8=
|
||||
github.com/mattn/go-sqlite3 v1.14.28 h1:ThEiQrnbtumT+QMknw63Befp/ce/nUPgBPMlRFEum7A=
|
||||
github.com/mattn/go-sqlite3 v1.14.28/go.mod h1:Uh1q+B4BYcTPb+yiD3kU8Ct7aC0hY9fxUwlHK0RXw+Y=
|
||||
github.com/nalgeon/be v0.2.0 h1:i1Rsh0F+aNnHdbgph5Cy8Xm5uMVeWrUpm1olgzlPsMo=
|
||||
github.com/nalgeon/be v0.2.0/go.mod h1:PMwMuBLopwKJkSHnr2qHyLcZYUTqNejN7A8RAqNWO3E=
|
||||
github.com/ncruces/go-sqlite3 v0.16.2 h1:HesVRr0BC6QSGSEQfEXOntFWS9wd4Z8ms4nJzfUv4Rg=
|
||||
github.com/ncruces/go-sqlite3 v0.16.2/go.mod h1:wkUIvOrAjFQnefVlivJfcowKUcfMHs4mvLfhVanzHHI=
|
||||
github.com/ncruces/go-strftime v0.1.9 h1:bY0MQC28UADQmHmaF5dgpLmImcShSi2kHU9XLdhx/f4=
|
||||
github.com/ncruces/go-strftime v0.1.9/go.mod h1:Fwc5htZGVVkseilnfgOVb9mKy6w1naJmn9CehxcKcls=
|
||||
github.com/ncruces/julianday v1.0.0 h1:fH0OKwa7NWvniGQtxdJRxAgkBMolni2BjDHaWTxqt7M=
|
||||
github.com/ncruces/julianday v1.0.0/go.mod h1:Dusn2KvZrrovOMJuOt0TNXL6tB7U2E8kvza5fFc9G7g=
|
||||
github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4=
|
||||
github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
|
||||
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
|
||||
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
|
||||
github.com/remyoudompheng/bigfft v0.0.0-20230129092748-24d4a6f8daec h1:W09IVJc94icq4NjY3clb7Lk8O1qJ8BdBEF8z0ibU0rE=
|
||||
github.com/remyoudompheng/bigfft v0.0.0-20230129092748-24d4a6f8daec/go.mod h1:qqbHyh8v60DhA7CoWK5oRCqLrMHRGoxYCSS9EjAz6Eo=
|
||||
github.com/tetratelabs/wazero v1.7.2 h1:1+z5nXJNwMLPAWaTePFi49SSTL0IMx/i3Fg8Yc25GDc=
|
||||
github.com/tetratelabs/wazero v1.7.2/go.mod h1:ytl6Zuh20R/eROuyDaGPkp82O9C/DJfXAwJfQ3X6/7Y=
|
||||
github.com/tetratelabs/wazero v1.7.3 h1:PBH5KVahrt3S2AHgEjKu4u+LlDbbk+nsGE3KLucy6Rw=
|
||||
github.com/tetratelabs/wazero v1.7.3/go.mod h1:ytl6Zuh20R/eROuyDaGPkp82O9C/DJfXAwJfQ3X6/7Y=
|
||||
github.com/tursodatabase/go-libsql v0.0.0-20240429120401-651096bbee0b h1:R7hev4b96zgXjKbS2ZNbHBnDvyFZhH+LlMqtKH6hIkU=
|
||||
github.com/tursodatabase/go-libsql v0.0.0-20240429120401-651096bbee0b/go.mod h1:TjsB2miB8RW2Sse8sdxzVTdeGlx74GloD5zJYUC38d8=
|
||||
golang.org/x/exp v0.0.0-20240325151524-a685a6edb6d8 h1:aAcj0Da7eBAtrTp03QXWvm88pSyOt+UgdZw2BFZ+lEw=
|
||||
golang.org/x/exp v0.0.0-20240325151524-a685a6edb6d8/go.mod h1:CQ1k9gNrJ50XIzaKCRR2hssIjF07kZFEiieALBM/ARQ=
|
||||
golang.org/x/mod v0.16.0 h1:QX4fJ0Rr5cPQCF7O9lh9Se4pmwfwskqZfq5moyldzic=
|
||||
golang.org/x/mod v0.16.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c=
|
||||
golang.org/x/sync v0.7.0 h1:YsImfSBoP9QPYL0xyKJPq0gcaJdG3rInoqxTWbfQu9M=
|
||||
golang.org/x/sync v0.7.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk=
|
||||
golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.21.0 h1:rF+pYz3DAGSQAxAu1CbC7catZg4ebC4UIeIhKxBZvws=
|
||||
golang.org/x/sys v0.21.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
|
||||
@@ -49,8 +35,6 @@ golang.org/x/text v0.16.0 h1:a94ExnEXNtEwYLGJSIUxnWoxoRz/ZcCsV63ROupILh4=
|
||||
golang.org/x/text v0.16.0/go.mod h1:GhwF1Be+LQoKShO3cGOHzqOgRrGaYc9AvblQOmPVHnI=
|
||||
golang.org/x/tools v0.19.0 h1:tfGCXNR1OsFG+sVdLAitlpjAvD/I6dHDKnYrpEZUHkw=
|
||||
golang.org/x/tools v0.19.0/go.mod h1:qoJWxmGSIBmAeriMx19ogtrEPrGtDbPK634QFIcLAhc=
|
||||
gotest.tools v2.2.0+incompatible h1:VsBPFP1AI068pPrMxtb/S8Zkgf9xEmTLJjfM+P5UIEo=
|
||||
gotest.tools v2.2.0+incompatible/go.mod h1:DsYFclhRJ6vuDpmuTbkuFWG+y2sxOXAzmJt81HFBacw=
|
||||
modernc.org/fileutil v1.3.0 h1:gQ5SIzK3H9kdfai/5x41oQiKValumqNTDXMvKo62HvE=
|
||||
modernc.org/fileutil v1.3.0/go.mod h1:XatxS8fZi3pS8/hKG2GH/ArUogfxjpEKs3Ku3aK4JyQ=
|
||||
modernc.org/gc/v3 v3.0.0-20240107210532-573471604cb6 h1:5D53IMaUuA5InSeMu9eJtlQXS2NxAhyWQvkKEgXZhHI=
|
||||
|
||||
@@ -1,37 +0,0 @@
|
||||
// An example of using Redka
|
||||
// with github.com/tursodatabase/go-libsql driver.
|
||||
package main
|
||||
|
||||
import (
|
||||
"log"
|
||||
"log/slog"
|
||||
|
||||
"github.com/nalgeon/redka"
|
||||
_ "github.com/tursodatabase/go-libsql"
|
||||
)
|
||||
|
||||
func main() {
|
||||
// libSQL uses a different driver name ("libsql" instead of "sqlite3").
|
||||
// It also does not support the journal_mode and mmap_size pragmas
|
||||
// (see https://github.com/tursodatabase/go-libsql/issues/28),
|
||||
// so we have to turn them off.
|
||||
opts := redka.Options{
|
||||
DriverName: "libsql",
|
||||
Pragma: map[string]string{
|
||||
"synchronous": "normal",
|
||||
"temp_store": "memory",
|
||||
"foreign_keys": "on",
|
||||
},
|
||||
}
|
||||
db, err := redka.Open("data.db", &opts)
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
defer db.Close()
|
||||
|
||||
err = db.Str().Set("name", "alice")
|
||||
slog.Info("set", "err", err)
|
||||
|
||||
count, err := db.Key().Count("name", "age", "city")
|
||||
slog.Info("count", "count", count, "err", err)
|
||||
}
|
||||
@@ -11,24 +11,22 @@ import (
|
||||
)
|
||||
|
||||
func main() {
|
||||
// Open a database.
|
||||
db, err := redka.Open("data.db", nil)
|
||||
// Open the database.
|
||||
db, err := redka.Open("redka.db", nil)
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
defer db.Close()
|
||||
defer func() { _ = db.Close() }()
|
||||
|
||||
// Set some string keys.
|
||||
// Set some values.
|
||||
err = db.Str().Set("name", "alice")
|
||||
slog.Info("set", "err", err)
|
||||
err = db.Str().Set("age", 25)
|
||||
slog.Info("set", "err", err)
|
||||
|
||||
// Check if the keys exist.
|
||||
count, err := db.Key().Count("name", "age", "city")
|
||||
slog.Info("count", "count", count, "err", err)
|
||||
|
||||
// Get a key.
|
||||
// Read them back.
|
||||
name, err := db.Str().Get("name")
|
||||
slog.Info("get", "name", name, "err", err)
|
||||
age, err := db.Str().Get("age")
|
||||
slog.Info("get", "age", age, "err", err)
|
||||
}
|
||||
@@ -16,15 +16,23 @@ func main() {
|
||||
opts := redka.Options{
|
||||
DriverName: "sqlite",
|
||||
}
|
||||
db, err := redka.Open("data.db", &opts)
|
||||
|
||||
// Open the database.
|
||||
db, err := redka.Open("redka.db", &opts)
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
defer db.Close()
|
||||
defer func() { _ = db.Close() }()
|
||||
|
||||
// Set some values.
|
||||
err = db.Str().Set("name", "alice")
|
||||
slog.Info("set", "err", err)
|
||||
err = db.Str().Set("age", 25)
|
||||
slog.Info("set", "err", err)
|
||||
|
||||
count, err := db.Key().Count("name", "age", "city")
|
||||
slog.Info("count", "count", count, "err", err)
|
||||
// Read them back.
|
||||
name, err := db.Str().Get("name")
|
||||
slog.Info("get", "name", name, "err", err)
|
||||
age, err := db.Str().Get("age")
|
||||
slog.Info("get", "age", age, "err", err)
|
||||
}
|
||||
|
||||
@@ -12,15 +12,22 @@ import (
|
||||
)
|
||||
|
||||
func main() {
|
||||
db, err := redka.Open("data.db", nil)
|
||||
// Open the database.
|
||||
db, err := redka.Open("redka.db", nil)
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
defer db.Close()
|
||||
defer func() { _ = db.Close() }()
|
||||
|
||||
// Set some values.
|
||||
err = db.Str().Set("name", "alice")
|
||||
slog.Info("set", "err", err)
|
||||
err = db.Str().Set("age", 25)
|
||||
slog.Info("set", "err", err)
|
||||
|
||||
count, err := db.Key().Count("name", "age", "city")
|
||||
slog.Info("count", "count", count, "err", err)
|
||||
// Read them back.
|
||||
name, err := db.Str().Get("name")
|
||||
slog.Info("get", "name", name, "err", err)
|
||||
age, err := db.Str().Get("age")
|
||||
slog.Info("get", "age", age, "err", err)
|
||||
}
|
||||
|
||||
36
example/postgres/main.go
Normal file
36
example/postgres/main.go
Normal file
@@ -0,0 +1,36 @@
|
||||
// An example of using Redka
|
||||
// with github.com/lib/pq driver.
|
||||
package main
|
||||
|
||||
import (
|
||||
"log"
|
||||
"log/slog"
|
||||
|
||||
_ "github.com/lib/pq"
|
||||
"github.com/nalgeon/redka"
|
||||
)
|
||||
|
||||
func main() {
|
||||
// Connections settings.
|
||||
connString := "postgres://redka:redka@localhost:5432/redka?sslmode=disable"
|
||||
opts := &redka.Options{DriverName: "postgres"}
|
||||
|
||||
// Open the database.
|
||||
db, err := redka.Open(connString, opts)
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
defer func() { _ = db.Close() }()
|
||||
|
||||
// Set some values.
|
||||
err = db.Str().Set("name", "alice")
|
||||
slog.Info("set", "err", err)
|
||||
err = db.Str().Set("age", 25)
|
||||
slog.Info("set", "err", err)
|
||||
|
||||
// Read them back.
|
||||
name, err := db.Str().Get("name")
|
||||
slog.Info("get", "name", name, "err", err)
|
||||
age, err := db.Str().Get("age")
|
||||
slog.Info("get", "age", age, "err", err)
|
||||
}
|
||||
@@ -10,11 +10,12 @@ import (
|
||||
)
|
||||
|
||||
func main() {
|
||||
db, err := redka.Open("data.db", nil)
|
||||
// Open the database.
|
||||
db, err := redka.Open("redka.db", nil)
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
defer db.Close()
|
||||
defer func() { _ = db.Close() }()
|
||||
|
||||
{
|
||||
// Writable transaction.
|
||||
|
||||
13
go.mod
13
go.mod
@@ -1,10 +1,17 @@
|
||||
module github.com/nalgeon/redka
|
||||
|
||||
go 1.22
|
||||
go 1.23.0
|
||||
|
||||
toolchain go1.24.0
|
||||
|
||||
// Main dependencies.
|
||||
require github.com/tidwall/redcon v1.6.2
|
||||
|
||||
// Test dependencies.
|
||||
require (
|
||||
github.com/mattn/go-sqlite3 v1.14.22
|
||||
github.com/tidwall/redcon v1.6.2
|
||||
github.com/lib/pq v1.10.9
|
||||
github.com/mattn/go-sqlite3 v1.14.28
|
||||
github.com/nalgeon/be v0.2.0
|
||||
)
|
||||
|
||||
require (
|
||||
|
||||
8
go.sum
8
go.sum
@@ -1,5 +1,9 @@
|
||||
github.com/mattn/go-sqlite3 v1.14.22 h1:2gZY6PC6kBnID23Tichd1K+Z0oS6nE/XwU+Vz/5o4kU=
|
||||
github.com/mattn/go-sqlite3 v1.14.22/go.mod h1:Uh1q+B4BYcTPb+yiD3kU8Ct7aC0hY9fxUwlHK0RXw+Y=
|
||||
github.com/lib/pq v1.10.9 h1:YXG7RB+JIjhP29X+OtkiDnYaXQwpS4JEWq7dtCCRUEw=
|
||||
github.com/lib/pq v1.10.9/go.mod h1:AlVN5x4E4T544tWzH6hKfbfQvm3HdbOxrmggDNAPY9o=
|
||||
github.com/mattn/go-sqlite3 v1.14.28 h1:ThEiQrnbtumT+QMknw63Befp/ce/nUPgBPMlRFEum7A=
|
||||
github.com/mattn/go-sqlite3 v1.14.28/go.mod h1:Uh1q+B4BYcTPb+yiD3kU8Ct7aC0hY9fxUwlHK0RXw+Y=
|
||||
github.com/nalgeon/be v0.2.0 h1:i1Rsh0F+aNnHdbgph5Cy8Xm5uMVeWrUpm1olgzlPsMo=
|
||||
github.com/nalgeon/be v0.2.0/go.mod h1:PMwMuBLopwKJkSHnr2qHyLcZYUTqNejN7A8RAqNWO3E=
|
||||
github.com/tidwall/btree v1.1.0/go.mod h1:TzIRzen6yHbibdSfK6t8QimqbUnoxUSrZfeW7Uob0q4=
|
||||
github.com/tidwall/btree v1.7.0 h1:L1fkJH/AuEh5zBnnBbmTwQ5Lt+bRJ5A8EWecslvo9iI=
|
||||
github.com/tidwall/btree v1.7.0/go.mod h1:twD9XRA5jj9VUQGELzDO4HPQTNJsoWWfYEL+EUQ2cKY=
|
||||
|
||||
@@ -3,15 +3,12 @@ package conn
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/nalgeon/redka"
|
||||
"github.com/nalgeon/redka/internal/redis"
|
||||
"github.com/nalgeon/redka/internal/testx"
|
||||
)
|
||||
|
||||
func getDB(tb testing.TB) (*redka.DB, redis.Redka) {
|
||||
func getRedka(tb testing.TB) redis.Redka {
|
||||
tb.Helper()
|
||||
db, err := redka.Open("file:/data.db?vfs=memdb", nil)
|
||||
if err != nil {
|
||||
tb.Fatal(err)
|
||||
}
|
||||
return db, redis.RedkaDB(db)
|
||||
db := testx.OpenDB(tb)
|
||||
return redis.RedkaDB(db)
|
||||
}
|
||||
|
||||
@@ -3,8 +3,8 @@ package conn
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/nalgeon/be"
|
||||
"github.com/nalgeon/redka/internal/redis"
|
||||
"github.com/nalgeon/redka/internal/testx"
|
||||
)
|
||||
|
||||
func TestEchoParse(t *testing.T) {
|
||||
@@ -34,19 +34,18 @@ func TestEchoParse(t *testing.T) {
|
||||
for _, test := range tests {
|
||||
t.Run(test.cmd, func(t *testing.T) {
|
||||
cmd, err := redis.Parse(ParseEcho, test.cmd)
|
||||
testx.AssertEqual(t, err, test.err)
|
||||
be.Equal(t, err, test.err)
|
||||
if err == nil {
|
||||
testx.AssertEqual(t, cmd.parts, test.want)
|
||||
be.Equal(t, cmd.parts, test.want)
|
||||
} else {
|
||||
testx.AssertEqual(t, cmd, Echo{})
|
||||
be.Equal(t, cmd, Echo{})
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestEchoExec(t *testing.T) {
|
||||
db, red := getDB(t)
|
||||
defer db.Close()
|
||||
red := getRedka(t)
|
||||
|
||||
tests := []struct {
|
||||
cmd string
|
||||
@@ -70,9 +69,9 @@ func TestEchoExec(t *testing.T) {
|
||||
conn := redis.NewFakeConn()
|
||||
cmd := redis.MustParse(ParseEcho, test.cmd)
|
||||
res, err := cmd.Run(conn, red)
|
||||
testx.AssertNoErr(t, err)
|
||||
testx.AssertEqual(t, res, test.res)
|
||||
testx.AssertEqual(t, conn.Out(), test.out)
|
||||
be.Err(t, err, nil)
|
||||
be.Equal(t, res, test.res)
|
||||
be.Equal(t, conn.Out(), test.out)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3,8 +3,8 @@ package conn
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/nalgeon/be"
|
||||
"github.com/nalgeon/redka/internal/redis"
|
||||
"github.com/nalgeon/redka/internal/testx"
|
||||
)
|
||||
|
||||
func TestPingParse(t *testing.T) {
|
||||
@@ -33,19 +33,18 @@ func TestPingParse(t *testing.T) {
|
||||
for _, test := range tests {
|
||||
t.Run(test.cmd, func(t *testing.T) {
|
||||
cmd, err := redis.Parse(ParsePing, test.cmd)
|
||||
testx.AssertEqual(t, err, test.err)
|
||||
be.Equal(t, err, test.err)
|
||||
if err == nil {
|
||||
testx.AssertEqual(t, cmd.message, test.want)
|
||||
be.Equal(t, cmd.message, test.want)
|
||||
} else {
|
||||
testx.AssertEqual(t, cmd, Ping{})
|
||||
be.Equal(t, cmd, Ping{})
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestPingExec(t *testing.T) {
|
||||
db, red := getDB(t)
|
||||
defer db.Close()
|
||||
red := getRedka(t)
|
||||
|
||||
tests := []struct {
|
||||
cmd string
|
||||
@@ -69,9 +68,9 @@ func TestPingExec(t *testing.T) {
|
||||
conn := redis.NewFakeConn()
|
||||
cmd := redis.MustParse(ParsePing, test.cmd)
|
||||
res, err := cmd.Run(conn, red)
|
||||
testx.AssertNoErr(t, err)
|
||||
testx.AssertEqual(t, res, test.res)
|
||||
testx.AssertEqual(t, conn.Out(), test.out)
|
||||
be.Err(t, err, nil)
|
||||
be.Equal(t, res, test.res)
|
||||
be.Equal(t, conn.Out(), test.out)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3,8 +3,8 @@ package conn
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/nalgeon/be"
|
||||
"github.com/nalgeon/redka/internal/redis"
|
||||
"github.com/nalgeon/redka/internal/testx"
|
||||
)
|
||||
|
||||
func TestSelectParse(t *testing.T) {
|
||||
@@ -33,19 +33,18 @@ func TestSelectParse(t *testing.T) {
|
||||
for _, test := range tests {
|
||||
t.Run(test.cmd, func(t *testing.T) {
|
||||
cmd, err := redis.Parse(ParseSelect, test.cmd)
|
||||
testx.AssertEqual(t, err, test.err)
|
||||
be.Equal(t, err, test.err)
|
||||
if err == nil {
|
||||
testx.AssertEqual(t, cmd.index, test.want.index)
|
||||
be.Equal(t, cmd.index, test.want.index)
|
||||
} else {
|
||||
testx.AssertEqual(t, cmd, Select{})
|
||||
be.Equal(t, cmd, Select{})
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestSelectExec(t *testing.T) {
|
||||
db, red := getDB(t)
|
||||
defer db.Close()
|
||||
red := getRedka(t)
|
||||
|
||||
tests := []struct {
|
||||
cmd string
|
||||
@@ -64,9 +63,9 @@ func TestSelectExec(t *testing.T) {
|
||||
conn := redis.NewFakeConn()
|
||||
cmd := redis.MustParse(ParseSelect, test.cmd)
|
||||
res, err := cmd.Run(conn, red)
|
||||
testx.AssertNoErr(t, err)
|
||||
testx.AssertEqual(t, res, test.res)
|
||||
testx.AssertEqual(t, conn.Out(), test.out)
|
||||
be.Err(t, err, nil)
|
||||
be.Equal(t, res, test.res)
|
||||
be.Equal(t, conn.Out(), test.out)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3,15 +3,12 @@ package hash
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/nalgeon/redka"
|
||||
"github.com/nalgeon/redka/internal/redis"
|
||||
"github.com/nalgeon/redka/internal/testx"
|
||||
)
|
||||
|
||||
func getDB(tb testing.TB) (*redka.DB, redis.Redka) {
|
||||
func getRedka(tb testing.TB) redis.Redka {
|
||||
tb.Helper()
|
||||
db, err := redka.Open("file:/data.db?vfs=memdb", nil)
|
||||
if err != nil {
|
||||
tb.Fatal(err)
|
||||
}
|
||||
return db, redis.RedkaDB(db)
|
||||
db := testx.OpenDB(tb)
|
||||
return redis.RedkaDB(db)
|
||||
}
|
||||
|
||||
@@ -3,9 +3,9 @@ package hash
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/nalgeon/be"
|
||||
"github.com/nalgeon/redka/internal/core"
|
||||
"github.com/nalgeon/redka/internal/redis"
|
||||
"github.com/nalgeon/redka/internal/testx"
|
||||
)
|
||||
|
||||
func TestHDelParse(t *testing.T) {
|
||||
@@ -44,12 +44,12 @@ func TestHDelParse(t *testing.T) {
|
||||
for _, test := range tests {
|
||||
t.Run(test.cmd, func(t *testing.T) {
|
||||
cmd, err := redis.Parse(ParseHDel, test.cmd)
|
||||
testx.AssertEqual(t, err, test.err)
|
||||
be.Equal(t, err, test.err)
|
||||
if err == nil {
|
||||
testx.AssertEqual(t, cmd.key, test.key)
|
||||
testx.AssertEqual(t, cmd.fields, test.fields)
|
||||
be.Equal(t, cmd.key, test.key)
|
||||
be.Equal(t, cmd.fields, test.fields)
|
||||
} else {
|
||||
testx.AssertEqual(t, cmd, HDel{})
|
||||
be.Equal(t, cmd, HDel{})
|
||||
}
|
||||
})
|
||||
}
|
||||
@@ -57,66 +57,63 @@ func TestHDelParse(t *testing.T) {
|
||||
|
||||
func TestHDelExec(t *testing.T) {
|
||||
t.Run("one", func(t *testing.T) {
|
||||
db, red := getDB(t)
|
||||
defer db.Close()
|
||||
red := getRedka(t)
|
||||
|
||||
_, _ = db.Hash().Set("person", "name", "alice")
|
||||
_, _ = db.Hash().Set("person", "age", 25)
|
||||
_, _ = red.Hash().Set("person", "name", "alice")
|
||||
_, _ = red.Hash().Set("person", "age", 25)
|
||||
|
||||
cmd := redis.MustParse(ParseHDel, "hdel person name")
|
||||
conn := redis.NewFakeConn()
|
||||
res, err := cmd.Run(conn, red)
|
||||
|
||||
testx.AssertNoErr(t, err)
|
||||
testx.AssertEqual(t, res, 1)
|
||||
testx.AssertEqual(t, conn.Out(), "1")
|
||||
be.Err(t, err, nil)
|
||||
be.Equal(t, res, 1)
|
||||
be.Equal(t, conn.Out(), "1")
|
||||
|
||||
_, err = db.Hash().Get("person", "name")
|
||||
testx.AssertErr(t, err, core.ErrNotFound)
|
||||
age, _ := db.Hash().Get("person", "age")
|
||||
testx.AssertEqual(t, age.String(), "25")
|
||||
_, err = red.Hash().Get("person", "name")
|
||||
be.Err(t, err, core.ErrNotFound)
|
||||
age, _ := red.Hash().Get("person", "age")
|
||||
be.Equal(t, age.String(), "25")
|
||||
})
|
||||
t.Run("some", func(t *testing.T) {
|
||||
db, red := getDB(t)
|
||||
defer db.Close()
|
||||
red := getRedka(t)
|
||||
|
||||
_, _ = db.Hash().Set("person", "name", "alice")
|
||||
_, _ = db.Hash().Set("person", "age", 25)
|
||||
_, _ = db.Hash().Set("person", "happy", true)
|
||||
_, _ = red.Hash().Set("person", "name", "alice")
|
||||
_, _ = red.Hash().Set("person", "age", 25)
|
||||
_, _ = red.Hash().Set("person", "happy", true)
|
||||
|
||||
cmd := redis.MustParse(ParseHDel, "hdel person name happy city")
|
||||
conn := redis.NewFakeConn()
|
||||
res, err := cmd.Run(conn, red)
|
||||
|
||||
testx.AssertNoErr(t, err)
|
||||
testx.AssertEqual(t, res, 2)
|
||||
testx.AssertEqual(t, conn.Out(), "2")
|
||||
be.Err(t, err, nil)
|
||||
be.Equal(t, res, 2)
|
||||
be.Equal(t, conn.Out(), "2")
|
||||
|
||||
_, err = db.Hash().Get("person", "name")
|
||||
testx.AssertErr(t, err, core.ErrNotFound)
|
||||
age, _ := db.Hash().Get("person", "age")
|
||||
testx.AssertEqual(t, age.String(), "25")
|
||||
_, err = db.Hash().Get("person", "happy")
|
||||
testx.AssertErr(t, err, core.ErrNotFound)
|
||||
_, err = red.Hash().Get("person", "name")
|
||||
be.Err(t, err, core.ErrNotFound)
|
||||
age, _ := red.Hash().Get("person", "age")
|
||||
be.Equal(t, age.String(), "25")
|
||||
_, err = red.Hash().Get("person", "happy")
|
||||
be.Err(t, err, core.ErrNotFound)
|
||||
})
|
||||
t.Run("all", func(t *testing.T) {
|
||||
db, red := getDB(t)
|
||||
defer db.Close()
|
||||
red := getRedka(t)
|
||||
|
||||
_, _ = db.Hash().Set("person", "name", "alice")
|
||||
_, _ = db.Hash().Set("person", "age", 25)
|
||||
_, _ = red.Hash().Set("person", "name", "alice")
|
||||
_, _ = red.Hash().Set("person", "age", 25)
|
||||
|
||||
cmd := redis.MustParse(ParseHDel, "hdel person name age")
|
||||
conn := redis.NewFakeConn()
|
||||
res, err := cmd.Run(conn, red)
|
||||
|
||||
testx.AssertNoErr(t, err)
|
||||
testx.AssertEqual(t, res, 2)
|
||||
testx.AssertEqual(t, conn.Out(), "2")
|
||||
be.Err(t, err, nil)
|
||||
be.Equal(t, res, 2)
|
||||
be.Equal(t, conn.Out(), "2")
|
||||
|
||||
_, err = db.Hash().Get("person", "name")
|
||||
testx.AssertErr(t, err, core.ErrNotFound)
|
||||
_, err = db.Hash().Get("person", "age")
|
||||
testx.AssertErr(t, err, core.ErrNotFound)
|
||||
_, err = red.Hash().Get("person", "name")
|
||||
be.Err(t, err, core.ErrNotFound)
|
||||
_, err = red.Hash().Get("person", "age")
|
||||
be.Err(t, err, core.ErrNotFound)
|
||||
})
|
||||
}
|
||||
|
||||
@@ -3,8 +3,8 @@ package hash
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/nalgeon/be"
|
||||
"github.com/nalgeon/redka/internal/redis"
|
||||
"github.com/nalgeon/redka/internal/testx"
|
||||
)
|
||||
|
||||
func TestHExistsParse(t *testing.T) {
|
||||
@@ -43,12 +43,12 @@ func TestHExistsParse(t *testing.T) {
|
||||
for _, test := range tests {
|
||||
t.Run(test.cmd, func(t *testing.T) {
|
||||
cmd, err := redis.Parse(ParseHExists, test.cmd)
|
||||
testx.AssertEqual(t, err, test.err)
|
||||
be.Equal(t, err, test.err)
|
||||
if err == nil {
|
||||
testx.AssertEqual(t, cmd.key, test.key)
|
||||
testx.AssertEqual(t, cmd.field, test.field)
|
||||
be.Equal(t, cmd.key, test.key)
|
||||
be.Equal(t, cmd.field, test.field)
|
||||
} else {
|
||||
testx.AssertEqual(t, cmd, HExists{})
|
||||
be.Equal(t, cmd, HExists{})
|
||||
}
|
||||
})
|
||||
}
|
||||
@@ -56,43 +56,40 @@ func TestHExistsParse(t *testing.T) {
|
||||
|
||||
func TestHExistsExec(t *testing.T) {
|
||||
t.Run("field found", func(t *testing.T) {
|
||||
db, red := getDB(t)
|
||||
defer db.Close()
|
||||
red := getRedka(t)
|
||||
|
||||
_, _ = db.Hash().Set("person", "name", "alice")
|
||||
_, _ = red.Hash().Set("person", "name", "alice")
|
||||
|
||||
cmd := redis.MustParse(ParseHExists, "hexists person name")
|
||||
conn := redis.NewFakeConn()
|
||||
res, err := cmd.Run(conn, red)
|
||||
|
||||
testx.AssertNoErr(t, err)
|
||||
testx.AssertEqual(t, res, true)
|
||||
testx.AssertEqual(t, conn.Out(), "1")
|
||||
be.Err(t, err, nil)
|
||||
be.Equal(t, res, true)
|
||||
be.Equal(t, conn.Out(), "1")
|
||||
})
|
||||
t.Run("field not found", func(t *testing.T) {
|
||||
db, red := getDB(t)
|
||||
defer db.Close()
|
||||
red := getRedka(t)
|
||||
|
||||
_, _ = db.Hash().Set("person", "name", "alice")
|
||||
_, _ = red.Hash().Set("person", "name", "alice")
|
||||
|
||||
cmd := redis.MustParse(ParseHExists, "hexists person age")
|
||||
conn := redis.NewFakeConn()
|
||||
res, err := cmd.Run(conn, red)
|
||||
|
||||
testx.AssertNoErr(t, err)
|
||||
testx.AssertEqual(t, res, false)
|
||||
testx.AssertEqual(t, conn.Out(), "0")
|
||||
be.Err(t, err, nil)
|
||||
be.Equal(t, res, false)
|
||||
be.Equal(t, conn.Out(), "0")
|
||||
})
|
||||
t.Run("key not found", func(t *testing.T) {
|
||||
db, red := getDB(t)
|
||||
defer db.Close()
|
||||
red := getRedka(t)
|
||||
|
||||
cmd := redis.MustParse(ParseHExists, "hexists person name")
|
||||
conn := redis.NewFakeConn()
|
||||
res, err := cmd.Run(conn, red)
|
||||
|
||||
testx.AssertNoErr(t, err)
|
||||
testx.AssertEqual(t, res, false)
|
||||
testx.AssertEqual(t, conn.Out(), "0")
|
||||
be.Err(t, err, nil)
|
||||
be.Equal(t, res, false)
|
||||
be.Equal(t, conn.Out(), "0")
|
||||
})
|
||||
}
|
||||
|
||||
@@ -3,9 +3,9 @@ package hash
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/nalgeon/be"
|
||||
"github.com/nalgeon/redka/internal/core"
|
||||
"github.com/nalgeon/redka/internal/redis"
|
||||
"github.com/nalgeon/redka/internal/testx"
|
||||
)
|
||||
|
||||
func TestHGetParse(t *testing.T) {
|
||||
@@ -44,12 +44,12 @@ func TestHGetParse(t *testing.T) {
|
||||
for _, test := range tests {
|
||||
t.Run(test.cmd, func(t *testing.T) {
|
||||
cmd, err := redis.Parse(ParseHGet, test.cmd)
|
||||
testx.AssertEqual(t, err, test.err)
|
||||
be.Equal(t, err, test.err)
|
||||
if err == nil {
|
||||
testx.AssertEqual(t, cmd.key, test.key)
|
||||
testx.AssertEqual(t, cmd.field, test.field)
|
||||
be.Equal(t, cmd.key, test.key)
|
||||
be.Equal(t, cmd.field, test.field)
|
||||
} else {
|
||||
testx.AssertEqual(t, cmd, HGet{})
|
||||
be.Equal(t, cmd, HGet{})
|
||||
}
|
||||
})
|
||||
}
|
||||
@@ -57,43 +57,38 @@ func TestHGetParse(t *testing.T) {
|
||||
|
||||
func TestHGetExec(t *testing.T) {
|
||||
t.Run("field found", func(t *testing.T) {
|
||||
db, red := getDB(t)
|
||||
defer db.Close()
|
||||
|
||||
_, _ = db.Hash().Set("person", "name", "alice")
|
||||
red := getRedka(t)
|
||||
_, _ = red.Hash().Set("person", "name", "alice")
|
||||
|
||||
cmd := redis.MustParse(ParseHGet, "hget person name")
|
||||
conn := redis.NewFakeConn()
|
||||
res, err := cmd.Run(conn, red)
|
||||
|
||||
testx.AssertNoErr(t, err)
|
||||
testx.AssertEqual(t, res, core.Value("alice"))
|
||||
testx.AssertEqual(t, conn.Out(), "alice")
|
||||
be.Err(t, err, nil)
|
||||
be.Equal(t, res.(core.Value), core.Value("alice"))
|
||||
be.Equal(t, conn.Out(), "alice")
|
||||
})
|
||||
t.Run("field not found", func(t *testing.T) {
|
||||
db, red := getDB(t)
|
||||
defer db.Close()
|
||||
|
||||
_, _ = db.Hash().Set("person", "name", "alice")
|
||||
red := getRedka(t)
|
||||
_, _ = red.Hash().Set("person", "name", "alice")
|
||||
|
||||
cmd := redis.MustParse(ParseHGet, "hget person age")
|
||||
conn := redis.NewFakeConn()
|
||||
res, err := cmd.Run(conn, red)
|
||||
|
||||
testx.AssertNoErr(t, err)
|
||||
testx.AssertEqual(t, res, core.Value(nil))
|
||||
testx.AssertEqual(t, conn.Out(), "(nil)")
|
||||
be.Err(t, err, nil)
|
||||
be.Equal(t, res.(core.Value), core.Value(nil))
|
||||
be.Equal(t, conn.Out(), "(nil)")
|
||||
})
|
||||
t.Run("key not found", func(t *testing.T) {
|
||||
db, red := getDB(t)
|
||||
defer db.Close()
|
||||
red := getRedka(t)
|
||||
|
||||
cmd := redis.MustParse(ParseHGet, "hget person name")
|
||||
conn := redis.NewFakeConn()
|
||||
res, err := cmd.Run(conn, red)
|
||||
|
||||
testx.AssertNoErr(t, err)
|
||||
testx.AssertEqual(t, res, core.Value(nil))
|
||||
testx.AssertEqual(t, conn.Out(), "(nil)")
|
||||
be.Err(t, err, nil)
|
||||
be.Equal(t, res.(core.Value), core.Value(nil))
|
||||
be.Equal(t, conn.Out(), "(nil)")
|
||||
})
|
||||
}
|
||||
|
||||
@@ -3,9 +3,9 @@ package hash
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/nalgeon/be"
|
||||
"github.com/nalgeon/redka/internal/core"
|
||||
"github.com/nalgeon/redka/internal/redis"
|
||||
"github.com/nalgeon/redka/internal/testx"
|
||||
)
|
||||
|
||||
func TestHGetAllParse(t *testing.T) {
|
||||
@@ -34,11 +34,11 @@ func TestHGetAllParse(t *testing.T) {
|
||||
for _, test := range tests {
|
||||
t.Run(test.cmd, func(t *testing.T) {
|
||||
cmd, err := redis.Parse(ParseHGetAll, test.cmd)
|
||||
testx.AssertEqual(t, err, test.err)
|
||||
be.Equal(t, err, test.err)
|
||||
if err == nil {
|
||||
testx.AssertEqual(t, cmd.key, test.key)
|
||||
be.Equal(t, cmd.key, test.key)
|
||||
} else {
|
||||
testx.AssertEqual(t, cmd, HGetAll{})
|
||||
be.Equal(t, cmd, HGetAll{})
|
||||
}
|
||||
})
|
||||
}
|
||||
@@ -46,34 +46,31 @@ func TestHGetAllParse(t *testing.T) {
|
||||
|
||||
func TestHGetAllExec(t *testing.T) {
|
||||
t.Run("key found", func(t *testing.T) {
|
||||
db, red := getDB(t)
|
||||
defer db.Close()
|
||||
|
||||
_, _ = db.Hash().Set("person", "name", "alice")
|
||||
_, _ = db.Hash().Set("person", "age", 25)
|
||||
red := getRedka(t)
|
||||
_, _ = red.Hash().Set("person", "name", "alice")
|
||||
_, _ = red.Hash().Set("person", "age", 25)
|
||||
|
||||
cmd := redis.MustParse(ParseHGetAll, "hgetall person")
|
||||
conn := redis.NewFakeConn()
|
||||
res, err := cmd.Run(conn, red)
|
||||
|
||||
testx.AssertNoErr(t, err)
|
||||
testx.AssertEqual(t, res, map[string]core.Value{
|
||||
be.Err(t, err, nil)
|
||||
be.Equal(t, res.(map[string]core.Value), map[string]core.Value{
|
||||
"name": core.Value("alice"), "age": core.Value("25"),
|
||||
})
|
||||
testx.AssertEqual(t,
|
||||
be.Equal(t,
|
||||
conn.Out() == "4,name,alice,age,25" || conn.Out() == "4,age,25,name,alice",
|
||||
true)
|
||||
})
|
||||
t.Run("key not found", func(t *testing.T) {
|
||||
db, red := getDB(t)
|
||||
defer db.Close()
|
||||
red := getRedka(t)
|
||||
|
||||
cmd := redis.MustParse(ParseHGetAll, "hgetall person")
|
||||
conn := redis.NewFakeConn()
|
||||
res, err := cmd.Run(conn, red)
|
||||
|
||||
testx.AssertNoErr(t, err)
|
||||
testx.AssertEqual(t, res, map[string]core.Value{})
|
||||
testx.AssertEqual(t, conn.Out(), "0")
|
||||
be.Err(t, err, nil)
|
||||
be.Equal(t, res.(map[string]core.Value), map[string]core.Value{})
|
||||
be.Equal(t, conn.Out(), "0")
|
||||
})
|
||||
}
|
||||
|
||||
@@ -3,9 +3,9 @@ package hash
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/nalgeon/be"
|
||||
"github.com/nalgeon/redka/internal/core"
|
||||
"github.com/nalgeon/redka/internal/redis"
|
||||
"github.com/nalgeon/redka/internal/testx"
|
||||
)
|
||||
|
||||
func TestHIncrByParse(t *testing.T) {
|
||||
@@ -46,13 +46,13 @@ func TestHIncrByParse(t *testing.T) {
|
||||
for _, test := range tests {
|
||||
t.Run(test.cmd, func(t *testing.T) {
|
||||
cmd, err := redis.Parse(ParseHIncrBy, test.cmd)
|
||||
testx.AssertEqual(t, err, test.err)
|
||||
be.Equal(t, err, test.err)
|
||||
if err == nil {
|
||||
testx.AssertEqual(t, cmd.key, test.key)
|
||||
testx.AssertEqual(t, cmd.field, test.field)
|
||||
testx.AssertEqual(t, cmd.delta, test.delta)
|
||||
be.Equal(t, cmd.key, test.key)
|
||||
be.Equal(t, cmd.field, test.field)
|
||||
be.Equal(t, cmd.delta, test.delta)
|
||||
} else {
|
||||
testx.AssertEqual(t, cmd, HIncrBy{})
|
||||
be.Equal(t, cmd, HIncrBy{})
|
||||
}
|
||||
})
|
||||
}
|
||||
@@ -60,69 +60,62 @@ func TestHIncrByParse(t *testing.T) {
|
||||
|
||||
func TestHIncrByExec(t *testing.T) {
|
||||
t.Run("incr field", func(t *testing.T) {
|
||||
db, red := getDB(t)
|
||||
defer db.Close()
|
||||
|
||||
_, _ = db.Hash().Set("person", "age", 25)
|
||||
red := getRedka(t)
|
||||
_, _ = red.Hash().Set("person", "age", 25)
|
||||
|
||||
cmd := redis.MustParse(ParseHIncrBy, "hincrby person age 10")
|
||||
conn := redis.NewFakeConn()
|
||||
res, err := cmd.Run(conn, red)
|
||||
|
||||
testx.AssertNoErr(t, err)
|
||||
testx.AssertEqual(t, res, 35)
|
||||
testx.AssertEqual(t, conn.Out(), "35")
|
||||
be.Err(t, err, nil)
|
||||
be.Equal(t, res, 35)
|
||||
be.Equal(t, conn.Out(), "35")
|
||||
|
||||
age, _ := db.Hash().Get("person", "age")
|
||||
testx.AssertEqual(t, age, core.Value("35"))
|
||||
age, _ := red.Hash().Get("person", "age")
|
||||
be.Equal(t, age, core.Value("35"))
|
||||
})
|
||||
t.Run("decr field", func(t *testing.T) {
|
||||
db, red := getDB(t)
|
||||
defer db.Close()
|
||||
|
||||
_, _ = db.Hash().Set("person", "age", 25)
|
||||
red := getRedka(t)
|
||||
_, _ = red.Hash().Set("person", "age", 25)
|
||||
|
||||
cmd := redis.MustParse(ParseHIncrBy, "hincrby person age -10")
|
||||
conn := redis.NewFakeConn()
|
||||
res, err := cmd.Run(conn, red)
|
||||
|
||||
testx.AssertNoErr(t, err)
|
||||
testx.AssertEqual(t, res, 15)
|
||||
testx.AssertEqual(t, conn.Out(), "15")
|
||||
be.Err(t, err, nil)
|
||||
be.Equal(t, res, 15)
|
||||
be.Equal(t, conn.Out(), "15")
|
||||
|
||||
age, _ := db.Hash().Get("person", "age")
|
||||
testx.AssertEqual(t, age, core.Value("15"))
|
||||
age, _ := red.Hash().Get("person", "age")
|
||||
be.Equal(t, age, core.Value("15"))
|
||||
})
|
||||
t.Run("create field", func(t *testing.T) {
|
||||
db, red := getDB(t)
|
||||
defer db.Close()
|
||||
|
||||
_, _ = db.Hash().Set("person", "name", "alice")
|
||||
red := getRedka(t)
|
||||
_, _ = red.Hash().Set("person", "name", "alice")
|
||||
|
||||
cmd := redis.MustParse(ParseHIncrBy, "hincrby person age 10")
|
||||
conn := redis.NewFakeConn()
|
||||
res, err := cmd.Run(conn, red)
|
||||
|
||||
testx.AssertNoErr(t, err)
|
||||
testx.AssertEqual(t, res, 10)
|
||||
testx.AssertEqual(t, conn.Out(), "10")
|
||||
be.Err(t, err, nil)
|
||||
be.Equal(t, res, 10)
|
||||
be.Equal(t, conn.Out(), "10")
|
||||
|
||||
age, _ := db.Hash().Get("person", "age")
|
||||
testx.AssertEqual(t, age, core.Value("10"))
|
||||
age, _ := red.Hash().Get("person", "age")
|
||||
be.Equal(t, age, core.Value("10"))
|
||||
})
|
||||
t.Run("create key", func(t *testing.T) {
|
||||
db, red := getDB(t)
|
||||
defer db.Close()
|
||||
red := getRedka(t)
|
||||
|
||||
cmd := redis.MustParse(ParseHIncrBy, "hincrby person age 10")
|
||||
conn := redis.NewFakeConn()
|
||||
res, err := cmd.Run(conn, red)
|
||||
|
||||
testx.AssertNoErr(t, err)
|
||||
testx.AssertEqual(t, res, 10)
|
||||
testx.AssertEqual(t, conn.Out(), "10")
|
||||
be.Err(t, err, nil)
|
||||
be.Equal(t, res, 10)
|
||||
be.Equal(t, conn.Out(), "10")
|
||||
|
||||
age, _ := db.Hash().Get("person", "age")
|
||||
testx.AssertEqual(t, age, core.Value("10"))
|
||||
age, _ := red.Hash().Get("person", "age")
|
||||
be.Equal(t, age, core.Value("10"))
|
||||
})
|
||||
}
|
||||
|
||||
@@ -3,9 +3,9 @@ package hash
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/nalgeon/be"
|
||||
"github.com/nalgeon/redka/internal/core"
|
||||
"github.com/nalgeon/redka/internal/redis"
|
||||
"github.com/nalgeon/redka/internal/testx"
|
||||
)
|
||||
|
||||
func TestHIncrByFloatParse(t *testing.T) {
|
||||
@@ -46,13 +46,13 @@ func TestHIncrByFloatParse(t *testing.T) {
|
||||
for _, test := range tests {
|
||||
t.Run(test.cmd, func(t *testing.T) {
|
||||
cmd, err := redis.Parse(ParseHIncrByFloat, test.cmd)
|
||||
testx.AssertEqual(t, err, test.err)
|
||||
be.Equal(t, err, test.err)
|
||||
if err == nil {
|
||||
testx.AssertEqual(t, cmd.key, test.key)
|
||||
testx.AssertEqual(t, cmd.field, test.field)
|
||||
testx.AssertEqual(t, cmd.delta, test.delta)
|
||||
be.Equal(t, cmd.key, test.key)
|
||||
be.Equal(t, cmd.field, test.field)
|
||||
be.Equal(t, cmd.delta, test.delta)
|
||||
} else {
|
||||
testx.AssertEqual(t, cmd, HIncrByFloat{})
|
||||
be.Equal(t, cmd, HIncrByFloat{})
|
||||
}
|
||||
})
|
||||
}
|
||||
@@ -60,69 +60,62 @@ func TestHIncrByFloatParse(t *testing.T) {
|
||||
|
||||
func TestHIncrByFloatExec(t *testing.T) {
|
||||
t.Run("incr field", func(t *testing.T) {
|
||||
db, red := getDB(t)
|
||||
defer db.Close()
|
||||
|
||||
_, _ = db.Hash().Set("person", "age", 25)
|
||||
red := getRedka(t)
|
||||
_, _ = red.Hash().Set("person", "age", 25)
|
||||
|
||||
cmd := redis.MustParse(ParseHIncrByFloat, "hincrbyfloat person age 10.5")
|
||||
conn := redis.NewFakeConn()
|
||||
res, err := cmd.Run(conn, red)
|
||||
|
||||
testx.AssertNoErr(t, err)
|
||||
testx.AssertEqual(t, res, 35.5)
|
||||
testx.AssertEqual(t, conn.Out(), "35.5")
|
||||
be.Err(t, err, nil)
|
||||
be.Equal(t, res, 35.5)
|
||||
be.Equal(t, conn.Out(), "35.5")
|
||||
|
||||
age, _ := db.Hash().Get("person", "age")
|
||||
testx.AssertEqual(t, age, core.Value("35.5"))
|
||||
age, _ := red.Hash().Get("person", "age")
|
||||
be.Equal(t, age, core.Value("35.5"))
|
||||
})
|
||||
t.Run("decr field", func(t *testing.T) {
|
||||
db, red := getDB(t)
|
||||
defer db.Close()
|
||||
|
||||
_, _ = db.Hash().Set("person", "age", 25)
|
||||
red := getRedka(t)
|
||||
_, _ = red.Hash().Set("person", "age", 25)
|
||||
|
||||
cmd := redis.MustParse(ParseHIncrByFloat, "hincrbyfloat person age -10.5")
|
||||
conn := redis.NewFakeConn()
|
||||
res, err := cmd.Run(conn, red)
|
||||
|
||||
testx.AssertNoErr(t, err)
|
||||
testx.AssertEqual(t, res, 14.5)
|
||||
testx.AssertEqual(t, conn.Out(), "14.5")
|
||||
be.Err(t, err, nil)
|
||||
be.Equal(t, res, 14.5)
|
||||
be.Equal(t, conn.Out(), "14.5")
|
||||
|
||||
age, _ := db.Hash().Get("person", "age")
|
||||
testx.AssertEqual(t, age, core.Value("14.5"))
|
||||
age, _ := red.Hash().Get("person", "age")
|
||||
be.Equal(t, age, core.Value("14.5"))
|
||||
})
|
||||
t.Run("create field", func(t *testing.T) {
|
||||
db, red := getDB(t)
|
||||
defer db.Close()
|
||||
|
||||
_, _ = db.Hash().Set("person", "name", "alice")
|
||||
red := getRedka(t)
|
||||
_, _ = red.Hash().Set("person", "name", "alice")
|
||||
|
||||
cmd := redis.MustParse(ParseHIncrByFloat, "hincrbyfloat person age 10.5")
|
||||
conn := redis.NewFakeConn()
|
||||
res, err := cmd.Run(conn, red)
|
||||
|
||||
testx.AssertNoErr(t, err)
|
||||
testx.AssertEqual(t, res, 10.5)
|
||||
testx.AssertEqual(t, conn.Out(), "10.5")
|
||||
be.Err(t, err, nil)
|
||||
be.Equal(t, res, 10.5)
|
||||
be.Equal(t, conn.Out(), "10.5")
|
||||
|
||||
age, _ := db.Hash().Get("person", "age")
|
||||
testx.AssertEqual(t, age, core.Value("10.5"))
|
||||
age, _ := red.Hash().Get("person", "age")
|
||||
be.Equal(t, age, core.Value("10.5"))
|
||||
})
|
||||
t.Run("create key", func(t *testing.T) {
|
||||
db, red := getDB(t)
|
||||
defer db.Close()
|
||||
red := getRedka(t)
|
||||
|
||||
cmd := redis.MustParse(ParseHIncrByFloat, "hincrbyfloat person age 10.5")
|
||||
conn := redis.NewFakeConn()
|
||||
res, err := cmd.Run(conn, red)
|
||||
|
||||
testx.AssertNoErr(t, err)
|
||||
testx.AssertEqual(t, res, 10.5)
|
||||
testx.AssertEqual(t, conn.Out(), "10.5")
|
||||
be.Err(t, err, nil)
|
||||
be.Equal(t, res, 10.5)
|
||||
be.Equal(t, conn.Out(), "10.5")
|
||||
|
||||
age, _ := db.Hash().Get("person", "age")
|
||||
testx.AssertEqual(t, age, core.Value("10.5"))
|
||||
age, _ := red.Hash().Get("person", "age")
|
||||
be.Equal(t, age, core.Value("10.5"))
|
||||
})
|
||||
}
|
||||
|
||||
@@ -1,10 +1,11 @@
|
||||
package hash
|
||||
|
||||
import (
|
||||
"slices"
|
||||
"testing"
|
||||
|
||||
"github.com/nalgeon/be"
|
||||
"github.com/nalgeon/redka/internal/redis"
|
||||
"github.com/nalgeon/redka/internal/testx"
|
||||
)
|
||||
|
||||
func TestHKeysParse(t *testing.T) {
|
||||
@@ -33,11 +34,11 @@ func TestHKeysParse(t *testing.T) {
|
||||
for _, test := range tests {
|
||||
t.Run(test.cmd, func(t *testing.T) {
|
||||
cmd, err := redis.Parse(ParseHKeys, test.cmd)
|
||||
testx.AssertEqual(t, err, test.err)
|
||||
be.Equal(t, err, test.err)
|
||||
if err == nil {
|
||||
testx.AssertEqual(t, cmd.key, test.key)
|
||||
be.Equal(t, cmd.key, test.key)
|
||||
} else {
|
||||
testx.AssertEqual(t, cmd, HKeys{})
|
||||
be.Equal(t, cmd, HKeys{})
|
||||
}
|
||||
})
|
||||
}
|
||||
@@ -45,32 +46,30 @@ func TestHKeysParse(t *testing.T) {
|
||||
|
||||
func TestHKeysExec(t *testing.T) {
|
||||
t.Run("key found", func(t *testing.T) {
|
||||
db, red := getDB(t)
|
||||
defer db.Close()
|
||||
red := getRedka(t)
|
||||
|
||||
_, _ = db.Hash().Set("person", "name", "alice")
|
||||
_, _ = db.Hash().Set("person", "age", 25)
|
||||
_, _ = red.Hash().Set("person", "name", "alice")
|
||||
_, _ = red.Hash().Set("person", "age", 25)
|
||||
|
||||
cmd := redis.MustParse(ParseHKeys, "hkeys person")
|
||||
conn := redis.NewFakeConn()
|
||||
res, err := cmd.Run(conn, red)
|
||||
|
||||
testx.AssertNoErr(t, err)
|
||||
testx.AssertEqual(t, res, []string{"age", "name"})
|
||||
testx.AssertEqual(t,
|
||||
conn.Out() == "2,age,name" || conn.Out() == "2,name,age",
|
||||
true)
|
||||
be.Err(t, err, nil)
|
||||
got := res.([]string)
|
||||
slices.Sort(got)
|
||||
be.Equal(t, got, []string{"age", "name"})
|
||||
be.True(t, conn.Out() == "2,age,name" || conn.Out() == "2,name,age")
|
||||
})
|
||||
t.Run("key not found", func(t *testing.T) {
|
||||
db, red := getDB(t)
|
||||
defer db.Close()
|
||||
red := getRedka(t)
|
||||
|
||||
cmd := redis.MustParse(ParseHKeys, "hkeys person")
|
||||
conn := redis.NewFakeConn()
|
||||
res, err := cmd.Run(conn, red)
|
||||
|
||||
testx.AssertNoErr(t, err)
|
||||
testx.AssertEqual(t, res, []string{})
|
||||
testx.AssertEqual(t, conn.Out(), "0")
|
||||
be.Err(t, err, nil)
|
||||
be.Equal(t, res.([]string), []string{})
|
||||
be.Equal(t, conn.Out(), "0")
|
||||
})
|
||||
}
|
||||
|
||||
@@ -3,8 +3,8 @@ package hash
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/nalgeon/be"
|
||||
"github.com/nalgeon/redka/internal/redis"
|
||||
"github.com/nalgeon/redka/internal/testx"
|
||||
)
|
||||
|
||||
func TestHLenParse(t *testing.T) {
|
||||
@@ -33,11 +33,11 @@ func TestHLenParse(t *testing.T) {
|
||||
for _, test := range tests {
|
||||
t.Run(test.cmd, func(t *testing.T) {
|
||||
cmd, err := redis.Parse(ParseHLen, test.cmd)
|
||||
testx.AssertEqual(t, err, test.err)
|
||||
be.Equal(t, err, test.err)
|
||||
if err == nil {
|
||||
testx.AssertEqual(t, cmd.key, test.key)
|
||||
be.Equal(t, cmd.key, test.key)
|
||||
} else {
|
||||
testx.AssertEqual(t, cmd, HLen{})
|
||||
be.Equal(t, cmd, HLen{})
|
||||
}
|
||||
})
|
||||
}
|
||||
@@ -45,30 +45,27 @@ func TestHLenParse(t *testing.T) {
|
||||
|
||||
func TestHLenExec(t *testing.T) {
|
||||
t.Run("key found", func(t *testing.T) {
|
||||
db, red := getDB(t)
|
||||
defer db.Close()
|
||||
|
||||
_, _ = db.Hash().Set("person", "name", "alice")
|
||||
_, _ = db.Hash().Set("person", "age", 25)
|
||||
red := getRedka(t)
|
||||
_, _ = red.Hash().Set("person", "name", "alice")
|
||||
_, _ = red.Hash().Set("person", "age", 25)
|
||||
|
||||
cmd := redis.MustParse(ParseHLen, "hlen person")
|
||||
conn := redis.NewFakeConn()
|
||||
res, err := cmd.Run(conn, red)
|
||||
|
||||
testx.AssertNoErr(t, err)
|
||||
testx.AssertEqual(t, res, 2)
|
||||
testx.AssertEqual(t, conn.Out(), "2")
|
||||
be.Err(t, err, nil)
|
||||
be.Equal(t, res, 2)
|
||||
be.Equal(t, conn.Out(), "2")
|
||||
})
|
||||
t.Run("key not found", func(t *testing.T) {
|
||||
db, red := getDB(t)
|
||||
defer db.Close()
|
||||
red := getRedka(t)
|
||||
|
||||
cmd := redis.MustParse(ParseHLen, "hlen person")
|
||||
conn := redis.NewFakeConn()
|
||||
res, err := cmd.Run(conn, red)
|
||||
|
||||
testx.AssertNoErr(t, err)
|
||||
testx.AssertEqual(t, res, 0)
|
||||
testx.AssertEqual(t, conn.Out(), "0")
|
||||
be.Err(t, err, nil)
|
||||
be.Equal(t, res, 0)
|
||||
be.Equal(t, conn.Out(), "0")
|
||||
})
|
||||
}
|
||||
|
||||
@@ -3,9 +3,9 @@ package hash
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/nalgeon/be"
|
||||
"github.com/nalgeon/redka/internal/core"
|
||||
"github.com/nalgeon/redka/internal/redis"
|
||||
"github.com/nalgeon/redka/internal/testx"
|
||||
)
|
||||
|
||||
func TestHMGetParse(t *testing.T) {
|
||||
@@ -44,12 +44,12 @@ func TestHMGetParse(t *testing.T) {
|
||||
for _, test := range tests {
|
||||
t.Run(test.cmd, func(t *testing.T) {
|
||||
cmd, err := redis.Parse(ParseHMGet, test.cmd)
|
||||
testx.AssertEqual(t, err, test.err)
|
||||
be.Equal(t, err, test.err)
|
||||
if err == nil {
|
||||
testx.AssertEqual(t, cmd.key, test.key)
|
||||
testx.AssertEqual(t, cmd.fields, test.fields)
|
||||
be.Equal(t, cmd.key, test.key)
|
||||
be.Equal(t, cmd.fields, test.fields)
|
||||
} else {
|
||||
testx.AssertEqual(t, cmd, HMGet{})
|
||||
be.Equal(t, cmd, HMGet{})
|
||||
}
|
||||
})
|
||||
}
|
||||
@@ -57,58 +57,52 @@ func TestHMGetParse(t *testing.T) {
|
||||
|
||||
func TestHMGetExec(t *testing.T) {
|
||||
t.Run("one field", func(t *testing.T) {
|
||||
db, red := getDB(t)
|
||||
defer db.Close()
|
||||
|
||||
_, _ = db.Hash().Set("person", "name", "alice")
|
||||
_, _ = db.Hash().Set("person", "age", 25)
|
||||
red := getRedka(t)
|
||||
_, _ = red.Hash().Set("person", "name", "alice")
|
||||
_, _ = red.Hash().Set("person", "age", 25)
|
||||
|
||||
cmd := redis.MustParse(ParseHMGet, "hmget person name")
|
||||
conn := redis.NewFakeConn()
|
||||
res, err := cmd.Run(conn, red)
|
||||
|
||||
testx.AssertNoErr(t, err)
|
||||
testx.AssertEqual(t, conn.Out(), "1,alice")
|
||||
be.Err(t, err, nil)
|
||||
be.Equal(t, conn.Out(), "1,alice")
|
||||
items := res.([]core.Value)
|
||||
testx.AssertEqual(t, len(items), 1)
|
||||
testx.AssertEqual(t, items[0], core.Value("alice"))
|
||||
be.Equal(t, len(items), 1)
|
||||
be.Equal(t, items[0], core.Value("alice"))
|
||||
})
|
||||
t.Run("some fields", func(t *testing.T) {
|
||||
db, red := getDB(t)
|
||||
defer db.Close()
|
||||
|
||||
_, _ = db.Hash().Set("person", "name", "alice")
|
||||
_, _ = db.Hash().Set("person", "age", 25)
|
||||
_, _ = db.Hash().Set("person", "happy", true)
|
||||
red := getRedka(t)
|
||||
_, _ = red.Hash().Set("person", "name", "alice")
|
||||
_, _ = red.Hash().Set("person", "age", 25)
|
||||
_, _ = red.Hash().Set("person", "happy", true)
|
||||
|
||||
cmd := redis.MustParse(ParseHMGet, "hmget person name happy city")
|
||||
conn := redis.NewFakeConn()
|
||||
res, err := cmd.Run(conn, red)
|
||||
|
||||
testx.AssertNoErr(t, err)
|
||||
testx.AssertEqual(t, conn.Out(), "3,alice,1,(nil)")
|
||||
be.Err(t, err, nil)
|
||||
be.Equal(t, conn.Out(), "3,alice,1,(nil)")
|
||||
items := res.([]core.Value)
|
||||
testx.AssertEqual(t, len(items), 3)
|
||||
testx.AssertEqual(t, items[0], core.Value("alice"))
|
||||
testx.AssertEqual(t, items[1], core.Value("1"))
|
||||
testx.AssertEqual(t, items[2], core.Value(nil))
|
||||
be.Equal(t, len(items), 3)
|
||||
be.Equal(t, items[0], core.Value("alice"))
|
||||
be.Equal(t, items[1], core.Value("1"))
|
||||
be.Equal(t, items[2], core.Value(nil))
|
||||
})
|
||||
t.Run("all fields", func(t *testing.T) {
|
||||
db, red := getDB(t)
|
||||
defer db.Close()
|
||||
|
||||
_, _ = db.Hash().Set("person", "name", "alice")
|
||||
_, _ = db.Hash().Set("person", "age", 25)
|
||||
red := getRedka(t)
|
||||
_, _ = red.Hash().Set("person", "name", "alice")
|
||||
_, _ = red.Hash().Set("person", "age", 25)
|
||||
|
||||
cmd := redis.MustParse(ParseHMGet, "hmget person name age")
|
||||
conn := redis.NewFakeConn()
|
||||
res, err := cmd.Run(conn, red)
|
||||
|
||||
testx.AssertNoErr(t, err)
|
||||
testx.AssertEqual(t, conn.Out(), "2,alice,25")
|
||||
be.Err(t, err, nil)
|
||||
be.Equal(t, conn.Out(), "2,alice,25")
|
||||
items := res.([]core.Value)
|
||||
testx.AssertEqual(t, len(items), 2)
|
||||
testx.AssertEqual(t, items[0], core.Value("alice"))
|
||||
testx.AssertEqual(t, items[1], core.Value("25"))
|
||||
be.Equal(t, len(items), 2)
|
||||
be.Equal(t, items[0], core.Value("alice"))
|
||||
be.Equal(t, items[1], core.Value("25"))
|
||||
})
|
||||
}
|
||||
|
||||
@@ -3,8 +3,8 @@ package hash
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/nalgeon/be"
|
||||
"github.com/nalgeon/redka/internal/redis"
|
||||
"github.com/nalgeon/redka/internal/testx"
|
||||
)
|
||||
|
||||
func TestHMSetParse(t *testing.T) {
|
||||
@@ -51,12 +51,12 @@ func TestHMSetParse(t *testing.T) {
|
||||
for _, test := range tests {
|
||||
t.Run(test.cmd, func(t *testing.T) {
|
||||
cmd, err := redis.Parse(ParseHMSet, test.cmd)
|
||||
testx.AssertEqual(t, err, test.err)
|
||||
be.Equal(t, err, test.err)
|
||||
if err == nil {
|
||||
testx.AssertEqual(t, cmd.key, test.want.key)
|
||||
testx.AssertEqual(t, cmd.items, test.want.items)
|
||||
be.Equal(t, cmd.key, test.want.key)
|
||||
be.Equal(t, cmd.items, test.want.items)
|
||||
} else {
|
||||
testx.AssertEqual(t, cmd, test.want)
|
||||
be.Equal(t, cmd, test.want)
|
||||
}
|
||||
})
|
||||
}
|
||||
@@ -64,73 +64,67 @@ func TestHMSetParse(t *testing.T) {
|
||||
|
||||
func TestHMSetExec(t *testing.T) {
|
||||
t.Run("create single", func(t *testing.T) {
|
||||
db, red := getDB(t)
|
||||
defer db.Close()
|
||||
red := getRedka(t)
|
||||
|
||||
cmd := redis.MustParse(ParseHMSet, "hmset person name alice")
|
||||
conn := redis.NewFakeConn()
|
||||
res, err := cmd.Run(conn, red)
|
||||
testx.AssertNoErr(t, err)
|
||||
testx.AssertEqual(t, res, 1)
|
||||
testx.AssertEqual(t, conn.Out(), "OK")
|
||||
be.Err(t, err, nil)
|
||||
be.Equal(t, res, 1)
|
||||
be.Equal(t, conn.Out(), "OK")
|
||||
|
||||
name, _ := db.Hash().Get("person", "name")
|
||||
testx.AssertEqual(t, name.String(), "alice")
|
||||
name, _ := red.Hash().Get("person", "name")
|
||||
be.Equal(t, name.String(), "alice")
|
||||
})
|
||||
|
||||
t.Run("create multiple", func(t *testing.T) {
|
||||
db, red := getDB(t)
|
||||
defer db.Close()
|
||||
red := getRedka(t)
|
||||
|
||||
cmd := redis.MustParse(ParseHMSet, "hmset person name alice age 25")
|
||||
conn := redis.NewFakeConn()
|
||||
res, err := cmd.Run(conn, red)
|
||||
testx.AssertNoErr(t, err)
|
||||
testx.AssertEqual(t, res, 2)
|
||||
testx.AssertEqual(t, conn.Out(), "OK")
|
||||
be.Err(t, err, nil)
|
||||
be.Equal(t, res, 2)
|
||||
be.Equal(t, conn.Out(), "OK")
|
||||
|
||||
name, _ := db.Hash().Get("person", "name")
|
||||
testx.AssertEqual(t, name.String(), "alice")
|
||||
age, _ := db.Hash().Get("person", "age")
|
||||
testx.AssertEqual(t, age.String(), "25")
|
||||
name, _ := red.Hash().Get("person", "name")
|
||||
be.Equal(t, name.String(), "alice")
|
||||
age, _ := red.Hash().Get("person", "age")
|
||||
be.Equal(t, age.String(), "25")
|
||||
})
|
||||
|
||||
t.Run("create/update", func(t *testing.T) {
|
||||
db, red := getDB(t)
|
||||
defer db.Close()
|
||||
|
||||
_, _ = db.Hash().Set("person", "name", "alice")
|
||||
red := getRedka(t)
|
||||
_, _ = red.Hash().Set("person", "name", "alice")
|
||||
|
||||
cmd := redis.MustParse(ParseHMSet, "hmset person name bob age 50")
|
||||
conn := redis.NewFakeConn()
|
||||
res, err := cmd.Run(conn, red)
|
||||
testx.AssertNoErr(t, err)
|
||||
testx.AssertEqual(t, res, 1)
|
||||
testx.AssertEqual(t, conn.Out(), "OK")
|
||||
be.Err(t, err, nil)
|
||||
be.Equal(t, res, 1)
|
||||
be.Equal(t, conn.Out(), "OK")
|
||||
|
||||
name, _ := db.Hash().Get("person", "name")
|
||||
testx.AssertEqual(t, name.String(), "bob")
|
||||
age, _ := db.Hash().Get("person", "age")
|
||||
testx.AssertEqual(t, age.String(), "50")
|
||||
name, _ := red.Hash().Get("person", "name")
|
||||
be.Equal(t, name.String(), "bob")
|
||||
age, _ := red.Hash().Get("person", "age")
|
||||
be.Equal(t, age.String(), "50")
|
||||
})
|
||||
|
||||
t.Run("update multiple", func(t *testing.T) {
|
||||
db, red := getDB(t)
|
||||
defer db.Close()
|
||||
|
||||
_, _ = db.Hash().Set("person", "name", "alice")
|
||||
_, _ = db.Hash().Set("person", "age", 25)
|
||||
red := getRedka(t)
|
||||
_, _ = red.Hash().Set("person", "name", "alice")
|
||||
_, _ = red.Hash().Set("person", "age", 25)
|
||||
|
||||
cmd := redis.MustParse(ParseHMSet, "hmset person name bob age 50")
|
||||
conn := redis.NewFakeConn()
|
||||
res, err := cmd.Run(conn, red)
|
||||
testx.AssertNoErr(t, err)
|
||||
testx.AssertEqual(t, res, 0)
|
||||
testx.AssertEqual(t, conn.Out(), "OK")
|
||||
be.Err(t, err, nil)
|
||||
be.Equal(t, res, 0)
|
||||
be.Equal(t, conn.Out(), "OK")
|
||||
|
||||
name, _ := db.Hash().Get("person", "name")
|
||||
testx.AssertEqual(t, name.String(), "bob")
|
||||
age, _ := db.Hash().Get("person", "age")
|
||||
testx.AssertEqual(t, age.String(), "50")
|
||||
name, _ := red.Hash().Get("person", "name")
|
||||
be.Equal(t, name.String(), "bob")
|
||||
age, _ := red.Hash().Get("person", "age")
|
||||
be.Equal(t, age.String(), "50")
|
||||
})
|
||||
}
|
||||
|
||||
@@ -1,12 +1,13 @@
|
||||
package hash
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"testing"
|
||||
|
||||
"github.com/nalgeon/be"
|
||||
"github.com/nalgeon/redka/internal/core"
|
||||
"github.com/nalgeon/redka/internal/redis"
|
||||
"github.com/nalgeon/redka/internal/rhash"
|
||||
"github.com/nalgeon/redka/internal/testx"
|
||||
)
|
||||
|
||||
func TestHScanParse(t *testing.T) {
|
||||
@@ -103,57 +104,62 @@ func TestHScanParse(t *testing.T) {
|
||||
for _, test := range tests {
|
||||
t.Run(test.cmd, func(t *testing.T) {
|
||||
cmd, err := redis.Parse(ParseHScan, test.cmd)
|
||||
testx.AssertEqual(t, err, test.err)
|
||||
be.Equal(t, err, test.err)
|
||||
if err == nil {
|
||||
testx.AssertEqual(t, cmd.key, test.key)
|
||||
testx.AssertEqual(t, cmd.cursor, test.cursor)
|
||||
testx.AssertEqual(t, cmd.match, test.match)
|
||||
testx.AssertEqual(t, cmd.count, test.count)
|
||||
be.Equal(t, cmd.key, test.key)
|
||||
be.Equal(t, cmd.cursor, test.cursor)
|
||||
be.Equal(t, cmd.match, test.match)
|
||||
be.Equal(t, cmd.count, test.count)
|
||||
} else {
|
||||
testx.AssertEqual(t, cmd, HScan{})
|
||||
be.Equal(t, cmd, HScan{})
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestHScanExec(t *testing.T) {
|
||||
db, red := getDB(t)
|
||||
defer db.Close()
|
||||
red := getRedka(t)
|
||||
|
||||
_, _ = db.Hash().Set("key", "f11", "11")
|
||||
_, _ = db.Hash().Set("key", "f12", "12")
|
||||
_, _ = db.Hash().Set("key", "f21", "21")
|
||||
_, _ = db.Hash().Set("key", "f22", "22")
|
||||
_, _ = db.Hash().Set("key", "f31", "31")
|
||||
_, _ = red.Hash().Set("key", "f11", "11")
|
||||
_, _ = red.Hash().Set("key", "f12", "12")
|
||||
_, _ = red.Hash().Set("key", "f21", "21")
|
||||
_, _ = red.Hash().Set("key", "f22", "22")
|
||||
_, _ = red.Hash().Set("key", "f31", "31")
|
||||
|
||||
t.Run("hscan all", func(t *testing.T) {
|
||||
var cursor int
|
||||
{
|
||||
// page 1
|
||||
cmd := redis.MustParse(ParseHScan, "hscan key 0")
|
||||
conn := redis.NewFakeConn()
|
||||
|
||||
res, err := cmd.Run(conn, red)
|
||||
testx.AssertNoErr(t, err)
|
||||
be.Err(t, err, nil)
|
||||
|
||||
sres := res.(rhash.ScanResult)
|
||||
testx.AssertEqual(t, sres.Cursor, 5)
|
||||
testx.AssertEqual(t, len(sres.Items), 5)
|
||||
testx.AssertEqual(t, sres.Items[0].Field, "f11")
|
||||
testx.AssertEqual(t, sres.Items[0].Value, core.Value("11"))
|
||||
testx.AssertEqual(t, sres.Items[4].Field, "f31")
|
||||
testx.AssertEqual(t, sres.Items[4].Value, core.Value("31"))
|
||||
testx.AssertEqual(t, conn.Out(), "2,5,10,f11,11,f12,12,f21,21,f22,22,f31,31")
|
||||
be.True(t, sres.Cursor > 0)
|
||||
be.Equal(t, len(sres.Items), 5)
|
||||
be.Equal(t, sres.Items[0].Field, "f11")
|
||||
be.Equal(t, sres.Items[0].Value, core.Value("11"))
|
||||
be.Equal(t, sres.Items[4].Field, "f31")
|
||||
be.Equal(t, sres.Items[4].Value, core.Value("31"))
|
||||
wantOut := fmt.Sprintf("2,%d,10,f11,11,f12,12,f21,21,f22,22,f31,31", sres.Cursor)
|
||||
be.Equal(t, conn.Out(), wantOut)
|
||||
cursor = sres.Cursor
|
||||
}
|
||||
{
|
||||
cmd := redis.MustParse(ParseHScan, "hscan key 5")
|
||||
// page 2 (empty)
|
||||
next := fmt.Sprintf("hscan key %d", cursor)
|
||||
cmd := redis.MustParse(ParseHScan, next)
|
||||
conn := redis.NewFakeConn()
|
||||
|
||||
res, err := cmd.Run(conn, red)
|
||||
testx.AssertNoErr(t, err)
|
||||
be.Err(t, err, nil)
|
||||
|
||||
sres := res.(rhash.ScanResult)
|
||||
testx.AssertEqual(t, sres.Cursor, 0)
|
||||
testx.AssertEqual(t, len(sres.Items), 0)
|
||||
testx.AssertEqual(t, conn.Out(), "2,0,0")
|
||||
be.Equal(t, sres.Cursor, 0)
|
||||
be.Equal(t, len(sres.Items), 0)
|
||||
be.Equal(t, conn.Out(), "2,0,0")
|
||||
}
|
||||
})
|
||||
|
||||
@@ -162,80 +168,91 @@ func TestHScanExec(t *testing.T) {
|
||||
conn := redis.NewFakeConn()
|
||||
|
||||
res, err := cmd.Run(conn, red)
|
||||
testx.AssertNoErr(t, err)
|
||||
be.Err(t, err, nil)
|
||||
|
||||
sres := res.(rhash.ScanResult)
|
||||
testx.AssertEqual(t, sres.Cursor, 4)
|
||||
testx.AssertEqual(t, len(sres.Items), 2)
|
||||
testx.AssertEqual(t, sres.Items[0].Field, "f21")
|
||||
testx.AssertEqual(t, sres.Items[0].Value, core.Value("21"))
|
||||
testx.AssertEqual(t, sres.Items[1].Field, "f22")
|
||||
testx.AssertEqual(t, sres.Items[1].Value, core.Value("22"))
|
||||
testx.AssertEqual(t, conn.Out(), "2,4,4,f21,21,f22,22")
|
||||
be.True(t, sres.Cursor > 0)
|
||||
be.Equal(t, len(sres.Items), 2)
|
||||
be.Equal(t, sres.Items[0].Field, "f21")
|
||||
be.Equal(t, sres.Items[0].Value, core.Value("21"))
|
||||
be.Equal(t, sres.Items[1].Field, "f22")
|
||||
be.Equal(t, sres.Items[1].Value, core.Value("22"))
|
||||
wantOut := fmt.Sprintf("2,%d,4,f21,21,f22,22", sres.Cursor)
|
||||
be.Equal(t, conn.Out(), wantOut)
|
||||
})
|
||||
|
||||
t.Run("hscan count", func(t *testing.T) {
|
||||
var cursor int
|
||||
{
|
||||
// page 1
|
||||
cmd := redis.MustParse(ParseHScan, "hscan key 0 match * count 2")
|
||||
conn := redis.NewFakeConn()
|
||||
|
||||
res, err := cmd.Run(conn, red)
|
||||
testx.AssertNoErr(t, err)
|
||||
be.Err(t, err, nil)
|
||||
|
||||
sres := res.(rhash.ScanResult)
|
||||
testx.AssertEqual(t, sres.Cursor, 2)
|
||||
testx.AssertEqual(t, len(sres.Items), 2)
|
||||
testx.AssertEqual(t, sres.Items[0].Field, "f11")
|
||||
testx.AssertEqual(t, sres.Items[0].Value, core.Value("11"))
|
||||
testx.AssertEqual(t, sres.Items[1].Field, "f12")
|
||||
testx.AssertEqual(t, sres.Items[1].Value, core.Value("12"))
|
||||
testx.AssertEqual(t, conn.Out(), "2,2,4,f11,11,f12,12")
|
||||
be.True(t, sres.Cursor > cursor)
|
||||
be.Equal(t, len(sres.Items), 2)
|
||||
be.Equal(t, sres.Items[0].Field, "f11")
|
||||
be.Equal(t, sres.Items[0].Value, core.Value("11"))
|
||||
be.Equal(t, sres.Items[1].Field, "f12")
|
||||
be.Equal(t, sres.Items[1].Value, core.Value("12"))
|
||||
wantOut := fmt.Sprintf("2,%d,4,f11,11,f12,12", sres.Cursor)
|
||||
be.Equal(t, conn.Out(), wantOut)
|
||||
cursor = sres.Cursor
|
||||
}
|
||||
{
|
||||
// page 2
|
||||
cmd := redis.MustParse(ParseHScan, "hscan key 2 match * count 2")
|
||||
next := fmt.Sprintf("hscan key %d match * count 2", cursor)
|
||||
cmd := redis.MustParse(ParseHScan, next)
|
||||
conn := redis.NewFakeConn()
|
||||
|
||||
res, err := cmd.Run(conn, red)
|
||||
testx.AssertNoErr(t, err)
|
||||
be.Err(t, err, nil)
|
||||
|
||||
sres := res.(rhash.ScanResult)
|
||||
testx.AssertEqual(t, sres.Cursor, 4)
|
||||
testx.AssertEqual(t, len(sres.Items), 2)
|
||||
testx.AssertEqual(t, sres.Items[0].Field, "f21")
|
||||
testx.AssertEqual(t, sres.Items[0].Value, core.Value("21"))
|
||||
testx.AssertEqual(t, sres.Items[1].Field, "f22")
|
||||
testx.AssertEqual(t, sres.Items[1].Value, core.Value("22"))
|
||||
testx.AssertEqual(t, conn.Out(), "2,4,4,f21,21,f22,22")
|
||||
be.True(t, sres.Cursor > cursor)
|
||||
be.Equal(t, len(sres.Items), 2)
|
||||
be.Equal(t, sres.Items[0].Field, "f21")
|
||||
be.Equal(t, sres.Items[0].Value, core.Value("21"))
|
||||
be.Equal(t, sres.Items[1].Field, "f22")
|
||||
be.Equal(t, sres.Items[1].Value, core.Value("22"))
|
||||
wantOut := fmt.Sprintf("2,%d,4,f21,21,f22,22", sres.Cursor)
|
||||
be.Equal(t, conn.Out(), wantOut)
|
||||
cursor = sres.Cursor
|
||||
}
|
||||
{
|
||||
// page 3
|
||||
cmd := redis.MustParse(ParseHScan, "hscan key 4 match * count 2")
|
||||
next := fmt.Sprintf("hscan key %d match * count 2", cursor)
|
||||
cmd := redis.MustParse(ParseHScan, next)
|
||||
conn := redis.NewFakeConn()
|
||||
|
||||
res, err := cmd.Run(conn, red)
|
||||
testx.AssertNoErr(t, err)
|
||||
be.Err(t, err, nil)
|
||||
|
||||
sres := res.(rhash.ScanResult)
|
||||
testx.AssertEqual(t, sres.Cursor, 5)
|
||||
testx.AssertEqual(t, len(sres.Items), 1)
|
||||
testx.AssertEqual(t, sres.Items[0].Field, "f31")
|
||||
testx.AssertEqual(t, sres.Items[0].Value, core.Value("31"))
|
||||
testx.AssertEqual(t, conn.Out(), "2,5,2,f31,31")
|
||||
be.True(t, sres.Cursor > cursor)
|
||||
be.Equal(t, len(sres.Items), 1)
|
||||
be.Equal(t, sres.Items[0].Field, "f31")
|
||||
be.Equal(t, sres.Items[0].Value, core.Value("31"))
|
||||
wantOut := fmt.Sprintf("2,%d,2,f31,31", sres.Cursor)
|
||||
be.Equal(t, conn.Out(), wantOut)
|
||||
cursor = sres.Cursor
|
||||
}
|
||||
{
|
||||
// no more pages
|
||||
cmd := redis.MustParse(ParseHScan, "hscan key 5 match * count 2")
|
||||
next := fmt.Sprintf("hscan key %d match * count 2", cursor)
|
||||
cmd := redis.MustParse(ParseHScan, next)
|
||||
conn := redis.NewFakeConn()
|
||||
|
||||
res, err := cmd.Run(conn, red)
|
||||
testx.AssertNoErr(t, err)
|
||||
be.Err(t, err, nil)
|
||||
|
||||
sres := res.(rhash.ScanResult)
|
||||
testx.AssertEqual(t, sres.Cursor, 0)
|
||||
testx.AssertEqual(t, len(sres.Items), 0)
|
||||
testx.AssertEqual(t, conn.Out(), "2,0,0")
|
||||
be.Equal(t, sres.Cursor, 0)
|
||||
be.Equal(t, len(sres.Items), 0)
|
||||
be.Equal(t, conn.Out(), "2,0,0")
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
@@ -3,8 +3,8 @@ package hash
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/nalgeon/be"
|
||||
"github.com/nalgeon/redka/internal/redis"
|
||||
"github.com/nalgeon/redka/internal/testx"
|
||||
)
|
||||
|
||||
func TestHSetParse(t *testing.T) {
|
||||
@@ -51,12 +51,12 @@ func TestHSetParse(t *testing.T) {
|
||||
for _, test := range tests {
|
||||
t.Run(test.cmd, func(t *testing.T) {
|
||||
cmd, err := redis.Parse(ParseHSet, test.cmd)
|
||||
testx.AssertEqual(t, err, test.err)
|
||||
be.Equal(t, err, test.err)
|
||||
if err == nil {
|
||||
testx.AssertEqual(t, cmd.key, test.want.key)
|
||||
testx.AssertEqual(t, cmd.items, test.want.items)
|
||||
be.Equal(t, cmd.key, test.want.key)
|
||||
be.Equal(t, cmd.items, test.want.items)
|
||||
} else {
|
||||
testx.AssertEqual(t, cmd, test.want)
|
||||
be.Equal(t, cmd, test.want)
|
||||
}
|
||||
})
|
||||
}
|
||||
@@ -64,73 +64,67 @@ func TestHSetParse(t *testing.T) {
|
||||
|
||||
func TestHSetExec(t *testing.T) {
|
||||
t.Run("create single", func(t *testing.T) {
|
||||
db, red := getDB(t)
|
||||
defer db.Close()
|
||||
red := getRedka(t)
|
||||
|
||||
cmd := redis.MustParse(ParseHSet, "hset person name alice")
|
||||
conn := redis.NewFakeConn()
|
||||
res, err := cmd.Run(conn, red)
|
||||
testx.AssertNoErr(t, err)
|
||||
testx.AssertEqual(t, res, 1)
|
||||
testx.AssertEqual(t, conn.Out(), "1")
|
||||
be.Err(t, err, nil)
|
||||
be.Equal(t, res, 1)
|
||||
be.Equal(t, conn.Out(), "1")
|
||||
|
||||
name, _ := db.Hash().Get("person", "name")
|
||||
testx.AssertEqual(t, name.String(), "alice")
|
||||
name, _ := red.Hash().Get("person", "name")
|
||||
be.Equal(t, name.String(), "alice")
|
||||
})
|
||||
|
||||
t.Run("create multiple", func(t *testing.T) {
|
||||
db, red := getDB(t)
|
||||
defer db.Close()
|
||||
red := getRedka(t)
|
||||
|
||||
cmd := redis.MustParse(ParseHSet, "hset person name alice age 25")
|
||||
conn := redis.NewFakeConn()
|
||||
res, err := cmd.Run(conn, red)
|
||||
testx.AssertNoErr(t, err)
|
||||
testx.AssertEqual(t, res, 2)
|
||||
testx.AssertEqual(t, conn.Out(), "2")
|
||||
be.Err(t, err, nil)
|
||||
be.Equal(t, res, 2)
|
||||
be.Equal(t, conn.Out(), "2")
|
||||
|
||||
name, _ := db.Hash().Get("person", "name")
|
||||
testx.AssertEqual(t, name.String(), "alice")
|
||||
age, _ := db.Hash().Get("person", "age")
|
||||
testx.AssertEqual(t, age.String(), "25")
|
||||
name, _ := red.Hash().Get("person", "name")
|
||||
be.Equal(t, name.String(), "alice")
|
||||
age, _ := red.Hash().Get("person", "age")
|
||||
be.Equal(t, age.String(), "25")
|
||||
})
|
||||
|
||||
t.Run("create/update", func(t *testing.T) {
|
||||
db, red := getDB(t)
|
||||
defer db.Close()
|
||||
|
||||
_, _ = db.Hash().Set("person", "name", "alice")
|
||||
red := getRedka(t)
|
||||
_, _ = red.Hash().Set("person", "name", "alice")
|
||||
|
||||
cmd := redis.MustParse(ParseHSet, "hset person name bob age 50")
|
||||
conn := redis.NewFakeConn()
|
||||
res, err := cmd.Run(conn, red)
|
||||
testx.AssertNoErr(t, err)
|
||||
testx.AssertEqual(t, res, 1)
|
||||
testx.AssertEqual(t, conn.Out(), "1")
|
||||
be.Err(t, err, nil)
|
||||
be.Equal(t, res, 1)
|
||||
be.Equal(t, conn.Out(), "1")
|
||||
|
||||
name, _ := db.Hash().Get("person", "name")
|
||||
testx.AssertEqual(t, name.String(), "bob")
|
||||
age, _ := db.Hash().Get("person", "age")
|
||||
testx.AssertEqual(t, age.String(), "50")
|
||||
name, _ := red.Hash().Get("person", "name")
|
||||
be.Equal(t, name.String(), "bob")
|
||||
age, _ := red.Hash().Get("person", "age")
|
||||
be.Equal(t, age.String(), "50")
|
||||
})
|
||||
|
||||
t.Run("update multiple", func(t *testing.T) {
|
||||
db, red := getDB(t)
|
||||
defer db.Close()
|
||||
|
||||
_, _ = db.Hash().Set("person", "name", "alice")
|
||||
_, _ = db.Hash().Set("person", "age", 25)
|
||||
red := getRedka(t)
|
||||
_, _ = red.Hash().Set("person", "name", "alice")
|
||||
_, _ = red.Hash().Set("person", "age", 25)
|
||||
|
||||
cmd := redis.MustParse(ParseHSet, "hset person name bob age 50")
|
||||
conn := redis.NewFakeConn()
|
||||
res, err := cmd.Run(conn, red)
|
||||
testx.AssertNoErr(t, err)
|
||||
testx.AssertEqual(t, res, 0)
|
||||
testx.AssertEqual(t, conn.Out(), "0")
|
||||
be.Err(t, err, nil)
|
||||
be.Equal(t, res, 0)
|
||||
be.Equal(t, conn.Out(), "0")
|
||||
|
||||
name, _ := db.Hash().Get("person", "name")
|
||||
testx.AssertEqual(t, name.String(), "bob")
|
||||
age, _ := db.Hash().Get("person", "age")
|
||||
testx.AssertEqual(t, age.String(), "50")
|
||||
name, _ := red.Hash().Get("person", "name")
|
||||
be.Equal(t, name.String(), "bob")
|
||||
age, _ := red.Hash().Get("person", "age")
|
||||
be.Equal(t, age.String(), "50")
|
||||
})
|
||||
}
|
||||
|
||||
@@ -3,8 +3,8 @@ package hash
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/nalgeon/be"
|
||||
"github.com/nalgeon/redka/internal/redis"
|
||||
"github.com/nalgeon/redka/internal/testx"
|
||||
)
|
||||
|
||||
func TestHSetNXParse(t *testing.T) {
|
||||
@@ -43,12 +43,12 @@ func TestHSetNXParse(t *testing.T) {
|
||||
for _, test := range tests {
|
||||
t.Run(test.cmd, func(t *testing.T) {
|
||||
cmd, err := redis.Parse(ParseHSetNX, test.cmd)
|
||||
testx.AssertEqual(t, err, test.err)
|
||||
be.Equal(t, err, test.err)
|
||||
if err == nil {
|
||||
testx.AssertEqual(t, cmd.key, test.want.key)
|
||||
testx.AssertEqual(t, cmd.value, test.want.value)
|
||||
be.Equal(t, cmd.key, test.want.key)
|
||||
be.Equal(t, cmd.value, test.want.value)
|
||||
} else {
|
||||
testx.AssertEqual(t, cmd, test.want)
|
||||
be.Equal(t, cmd, test.want)
|
||||
}
|
||||
})
|
||||
}
|
||||
@@ -56,34 +56,31 @@ func TestHSetNXParse(t *testing.T) {
|
||||
|
||||
func TestHSetNXExec(t *testing.T) {
|
||||
t.Run("create", func(t *testing.T) {
|
||||
db, red := getDB(t)
|
||||
defer db.Close()
|
||||
red := getRedka(t)
|
||||
|
||||
cmd := redis.MustParse(ParseHSetNX, "hsetnx person name alice")
|
||||
conn := redis.NewFakeConn()
|
||||
res, err := cmd.Run(conn, red)
|
||||
testx.AssertNoErr(t, err)
|
||||
testx.AssertEqual(t, res, true)
|
||||
testx.AssertEqual(t, conn.Out(), "1")
|
||||
be.Err(t, err, nil)
|
||||
be.Equal(t, res, true)
|
||||
be.Equal(t, conn.Out(), "1")
|
||||
|
||||
name, _ := db.Hash().Get("person", "name")
|
||||
testx.AssertEqual(t, name.String(), "alice")
|
||||
name, _ := red.Hash().Get("person", "name")
|
||||
be.Equal(t, name.String(), "alice")
|
||||
})
|
||||
|
||||
t.Run("update", func(t *testing.T) {
|
||||
db, red := getDB(t)
|
||||
defer db.Close()
|
||||
|
||||
_, _ = db.Hash().Set("person", "name", "alice")
|
||||
red := getRedka(t)
|
||||
_, _ = red.Hash().Set("person", "name", "alice")
|
||||
|
||||
cmd := redis.MustParse(ParseHSetNX, "hsetnx person name bob")
|
||||
conn := redis.NewFakeConn()
|
||||
res, err := cmd.Run(conn, red)
|
||||
testx.AssertNoErr(t, err)
|
||||
testx.AssertEqual(t, res, false)
|
||||
testx.AssertEqual(t, conn.Out(), "0")
|
||||
be.Err(t, err, nil)
|
||||
be.Equal(t, res, false)
|
||||
be.Equal(t, conn.Out(), "0")
|
||||
|
||||
name, _ := db.Hash().Get("person", "name")
|
||||
testx.AssertEqual(t, name.String(), "alice")
|
||||
name, _ := red.Hash().Get("person", "name")
|
||||
be.Equal(t, name.String(), "alice")
|
||||
})
|
||||
}
|
||||
|
||||
@@ -1,11 +1,12 @@
|
||||
package hash
|
||||
|
||||
import (
|
||||
"slices"
|
||||
"testing"
|
||||
|
||||
"github.com/nalgeon/be"
|
||||
"github.com/nalgeon/redka/internal/core"
|
||||
"github.com/nalgeon/redka/internal/redis"
|
||||
"github.com/nalgeon/redka/internal/testx"
|
||||
)
|
||||
|
||||
func TestHValsParse(t *testing.T) {
|
||||
@@ -34,11 +35,11 @@ func TestHValsParse(t *testing.T) {
|
||||
for _, test := range tests {
|
||||
t.Run(test.cmd, func(t *testing.T) {
|
||||
cmd, err := redis.Parse(ParseHVals, test.cmd)
|
||||
testx.AssertEqual(t, err, test.err)
|
||||
be.Equal(t, err, test.err)
|
||||
if err == nil {
|
||||
testx.AssertEqual(t, cmd.key, test.key)
|
||||
be.Equal(t, cmd.key, test.key)
|
||||
} else {
|
||||
testx.AssertEqual(t, cmd, HVals{})
|
||||
be.Equal(t, cmd, HVals{})
|
||||
}
|
||||
})
|
||||
}
|
||||
@@ -46,30 +47,32 @@ func TestHValsParse(t *testing.T) {
|
||||
|
||||
func TestHValsExec(t *testing.T) {
|
||||
t.Run("key found", func(t *testing.T) {
|
||||
db, red := getDB(t)
|
||||
defer db.Close()
|
||||
|
||||
_, _ = db.Hash().Set("person", "name", "alice")
|
||||
_, _ = db.Hash().Set("person", "age", 25)
|
||||
red := getRedka(t)
|
||||
_, _ = red.Hash().Set("person", "name", "alice")
|
||||
_, _ = red.Hash().Set("person", "age", 25)
|
||||
|
||||
cmd := redis.MustParse(ParseHVals, "hvals person")
|
||||
conn := redis.NewFakeConn()
|
||||
res, err := cmd.Run(conn, red)
|
||||
|
||||
testx.AssertNoErr(t, err)
|
||||
testx.AssertEqual(t, res, []core.Value{core.Value("25"), core.Value("alice")})
|
||||
testx.AssertEqual(t, conn.Out(), "2,25,alice")
|
||||
be.Err(t, err, nil)
|
||||
var got []string
|
||||
for _, val := range res.([]core.Value) {
|
||||
got = append(got, val.String())
|
||||
}
|
||||
slices.Sort(got)
|
||||
be.Equal(t, got, []string{"25", "alice"})
|
||||
be.True(t, conn.Out() == "2,25,alice" || conn.Out() == "2,alice,25")
|
||||
})
|
||||
t.Run("key not found", func(t *testing.T) {
|
||||
db, red := getDB(t)
|
||||
defer db.Close()
|
||||
red := getRedka(t)
|
||||
|
||||
cmd := redis.MustParse(ParseHVals, "hvals person")
|
||||
conn := redis.NewFakeConn()
|
||||
res, err := cmd.Run(conn, red)
|
||||
|
||||
testx.AssertNoErr(t, err)
|
||||
testx.AssertEqual(t, res, []core.Value{})
|
||||
testx.AssertEqual(t, conn.Out(), "0")
|
||||
be.Err(t, err, nil)
|
||||
be.Equal(t, res.([]core.Value), []core.Value{})
|
||||
be.Equal(t, conn.Out(), "0")
|
||||
})
|
||||
}
|
||||
|
||||
@@ -3,9 +3,9 @@ package key
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/nalgeon/be"
|
||||
"github.com/nalgeon/redka/internal/core"
|
||||
"github.com/nalgeon/redka/internal/redis"
|
||||
"github.com/nalgeon/redka/internal/testx"
|
||||
)
|
||||
|
||||
func TestDelParse(t *testing.T) {
|
||||
@@ -34,11 +34,11 @@ func TestDelParse(t *testing.T) {
|
||||
for _, test := range tests {
|
||||
t.Run(test.cmd, func(t *testing.T) {
|
||||
cmd, err := redis.Parse(ParseDel, test.cmd)
|
||||
testx.AssertEqual(t, err, test.err)
|
||||
be.Equal(t, err, test.err)
|
||||
if err == nil {
|
||||
testx.AssertEqual(t, cmd.keys, test.want)
|
||||
be.Equal(t, cmd.keys, test.want)
|
||||
} else {
|
||||
testx.AssertEqual(t, cmd, Del{})
|
||||
be.Equal(t, cmd, Del{})
|
||||
}
|
||||
})
|
||||
}
|
||||
@@ -69,24 +69,23 @@ func TestDelExec(t *testing.T) {
|
||||
|
||||
for _, test := range tests {
|
||||
t.Run(test.cmd, func(t *testing.T) {
|
||||
db, red := getDB(t)
|
||||
defer db.Close()
|
||||
red := getRedka(t)
|
||||
|
||||
_ = db.Str().Set("name", "alice")
|
||||
_ = db.Str().Set("age", 50)
|
||||
_ = db.Str().Set("city", "paris")
|
||||
_ = red.Str().Set("name", "alice")
|
||||
_ = red.Str().Set("age", 50)
|
||||
_ = red.Str().Set("city", "paris")
|
||||
|
||||
conn := redis.NewFakeConn()
|
||||
cmd := redis.MustParse(ParseDel, test.cmd)
|
||||
res, err := cmd.Run(conn, red)
|
||||
testx.AssertNoErr(t, err)
|
||||
testx.AssertEqual(t, res, test.res)
|
||||
testx.AssertEqual(t, conn.Out(), test.out)
|
||||
be.Err(t, err, nil)
|
||||
be.Equal(t, res, test.res)
|
||||
be.Equal(t, conn.Out(), test.out)
|
||||
|
||||
_, err = db.Str().Get("name")
|
||||
testx.AssertErr(t, err, core.ErrNotFound)
|
||||
city, _ := db.Str().Get("city")
|
||||
testx.AssertEqual(t, city.String(), "paris")
|
||||
_, err = red.Str().Get("name")
|
||||
be.Err(t, err, core.ErrNotFound)
|
||||
city, _ := red.Str().Get("city")
|
||||
be.Equal(t, city.String(), "paris")
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3,8 +3,8 @@ package key
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/nalgeon/be"
|
||||
"github.com/nalgeon/redka/internal/redis"
|
||||
"github.com/nalgeon/redka/internal/testx"
|
||||
)
|
||||
|
||||
func TestExistsParse(t *testing.T) {
|
||||
@@ -33,23 +33,22 @@ func TestExistsParse(t *testing.T) {
|
||||
for _, test := range tests {
|
||||
t.Run(test.cmd, func(t *testing.T) {
|
||||
cmd, err := redis.Parse(ParseExists, test.cmd)
|
||||
testx.AssertEqual(t, err, test.err)
|
||||
be.Equal(t, err, test.err)
|
||||
if err == nil {
|
||||
testx.AssertEqual(t, cmd.keys, test.want)
|
||||
be.Equal(t, cmd.keys, test.want)
|
||||
} else {
|
||||
testx.AssertEqual(t, cmd, Exists{})
|
||||
be.Equal(t, cmd, Exists{})
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestExistsExec(t *testing.T) {
|
||||
db, red := getDB(t)
|
||||
defer db.Close()
|
||||
red := getRedka(t)
|
||||
|
||||
_ = db.Str().Set("name", "alice")
|
||||
_ = db.Str().Set("age", 50)
|
||||
_ = db.Str().Set("city", "paris")
|
||||
_ = red.Str().Set("name", "alice")
|
||||
_ = red.Str().Set("age", 50)
|
||||
_ = red.Str().Set("city", "paris")
|
||||
|
||||
tests := []struct {
|
||||
cmd string
|
||||
@@ -78,9 +77,9 @@ func TestExistsExec(t *testing.T) {
|
||||
conn := redis.NewFakeConn()
|
||||
cmd := redis.MustParse(ParseExists, test.cmd)
|
||||
res, err := cmd.Run(conn, red)
|
||||
testx.AssertNoErr(t, err)
|
||||
testx.AssertEqual(t, res, test.res)
|
||||
testx.AssertEqual(t, conn.Out(), test.out)
|
||||
be.Err(t, err, nil)
|
||||
be.Equal(t, res, test.res)
|
||||
be.Equal(t, conn.Out(), test.out)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
@@ -4,8 +4,8 @@ import (
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"github.com/nalgeon/be"
|
||||
"github.com/nalgeon/redka/internal/redis"
|
||||
"github.com/nalgeon/redka/internal/testx"
|
||||
)
|
||||
|
||||
func TestExpireParse(t *testing.T) {
|
||||
@@ -54,12 +54,12 @@ func TestExpireParse(t *testing.T) {
|
||||
for _, test := range tests {
|
||||
t.Run(test.cmd, func(t *testing.T) {
|
||||
cmd, err := redis.Parse(parse, test.cmd)
|
||||
testx.AssertEqual(t, err, test.err)
|
||||
be.Equal(t, err, test.err)
|
||||
if err == nil {
|
||||
testx.AssertEqual(t, cmd.key, test.key)
|
||||
testx.AssertEqual(t, cmd.ttl, test.ttl)
|
||||
be.Equal(t, cmd.key, test.key)
|
||||
be.Equal(t, cmd.ttl, test.ttl)
|
||||
} else {
|
||||
testx.AssertEqual(t, cmd, Expire{})
|
||||
be.Equal(t, cmd, Expire{})
|
||||
}
|
||||
})
|
||||
}
|
||||
@@ -70,89 +70,79 @@ func TestExpireExec(t *testing.T) {
|
||||
return ParseExpire(b, 1000)
|
||||
}
|
||||
t.Run("create expire", func(t *testing.T) {
|
||||
db, red := getDB(t)
|
||||
defer db.Close()
|
||||
|
||||
_ = db.Str().Set("name", "alice")
|
||||
red := getRedka(t)
|
||||
_ = red.Str().Set("name", "alice")
|
||||
|
||||
cmd := redis.MustParse(parse, "expire name 60")
|
||||
conn := redis.NewFakeConn()
|
||||
res, err := cmd.Run(conn, red)
|
||||
testx.AssertNoErr(t, err)
|
||||
testx.AssertEqual(t, res, true)
|
||||
testx.AssertEqual(t, conn.Out(), "1")
|
||||
be.Err(t, err, nil)
|
||||
be.Equal(t, res, true)
|
||||
be.Equal(t, conn.Out(), "1")
|
||||
|
||||
expireAt := time.Now().Add(60 * time.Second)
|
||||
key, _ := db.Key().Get("name")
|
||||
testx.AssertEqual(t, *key.ETime/1000, expireAt.UnixMilli()/1000)
|
||||
key, _ := red.Key().Get("name")
|
||||
be.Equal(t, *key.ETime/1000, expireAt.UnixMilli()/1000)
|
||||
})
|
||||
|
||||
t.Run("update expire", func(t *testing.T) {
|
||||
db, red := getDB(t)
|
||||
defer db.Close()
|
||||
|
||||
_ = db.Str().SetExpires("name", "alice", 60*time.Second)
|
||||
red := getRedka(t)
|
||||
_ = red.Str().SetExpires("name", "alice", 60*time.Second)
|
||||
|
||||
cmd := redis.MustParse(parse, "expire name 30")
|
||||
conn := redis.NewFakeConn()
|
||||
res, err := cmd.Run(conn, red)
|
||||
testx.AssertNoErr(t, err)
|
||||
testx.AssertEqual(t, res, true)
|
||||
testx.AssertEqual(t, conn.Out(), "1")
|
||||
be.Err(t, err, nil)
|
||||
be.Equal(t, res, true)
|
||||
be.Equal(t, conn.Out(), "1")
|
||||
|
||||
expireAt := time.Now().Add(30 * time.Second)
|
||||
key, _ := db.Key().Get("name")
|
||||
testx.AssertEqual(t, *key.ETime/1000, expireAt.UnixMilli()/1000)
|
||||
key, _ := red.Key().Get("name")
|
||||
be.Equal(t, *key.ETime/1000, expireAt.UnixMilli()/1000)
|
||||
})
|
||||
|
||||
t.Run("set to zero", func(t *testing.T) {
|
||||
db, red := getDB(t)
|
||||
defer db.Close()
|
||||
|
||||
_ = db.Str().Set("name", "alice")
|
||||
red := getRedka(t)
|
||||
_ = red.Str().Set("name", "alice")
|
||||
|
||||
cmd := redis.MustParse(parse, "expire name 0")
|
||||
conn := redis.NewFakeConn()
|
||||
res, err := cmd.Run(conn, red)
|
||||
testx.AssertNoErr(t, err)
|
||||
testx.AssertEqual(t, res, true)
|
||||
testx.AssertEqual(t, conn.Out(), "1")
|
||||
be.Err(t, err, nil)
|
||||
be.Equal(t, res, true)
|
||||
be.Equal(t, conn.Out(), "1")
|
||||
|
||||
key, _ := db.Key().Get("name")
|
||||
testx.AssertEqual(t, key.Exists(), false)
|
||||
key, _ := red.Key().Get("name")
|
||||
be.Equal(t, key.Exists(), false)
|
||||
})
|
||||
|
||||
t.Run("negative", func(t *testing.T) {
|
||||
db, red := getDB(t)
|
||||
defer db.Close()
|
||||
|
||||
_ = db.Str().Set("name", "alice")
|
||||
red := getRedka(t)
|
||||
_ = red.Str().Set("name", "alice")
|
||||
|
||||
cmd := redis.MustParse(parse, "expire name -10")
|
||||
conn := redis.NewFakeConn()
|
||||
res, err := cmd.Run(conn, red)
|
||||
testx.AssertNoErr(t, err)
|
||||
testx.AssertEqual(t, res, true)
|
||||
testx.AssertEqual(t, conn.Out(), "1")
|
||||
be.Err(t, err, nil)
|
||||
be.Equal(t, res, true)
|
||||
be.Equal(t, conn.Out(), "1")
|
||||
|
||||
key, _ := db.Key().Get("name")
|
||||
testx.AssertEqual(t, key.Exists(), false)
|
||||
key, _ := red.Key().Get("name")
|
||||
be.Equal(t, key.Exists(), false)
|
||||
})
|
||||
|
||||
t.Run("not found", func(t *testing.T) {
|
||||
db, red := getDB(t)
|
||||
defer db.Close()
|
||||
|
||||
_ = db.Str().Set("name", "alice")
|
||||
red := getRedka(t)
|
||||
_ = red.Str().Set("name", "alice")
|
||||
|
||||
cmd := redis.MustParse(parse, "expire age 60")
|
||||
conn := redis.NewFakeConn()
|
||||
res, err := cmd.Run(conn, red)
|
||||
testx.AssertNoErr(t, err)
|
||||
testx.AssertEqual(t, res, false)
|
||||
testx.AssertEqual(t, conn.Out(), "0")
|
||||
be.Err(t, err, nil)
|
||||
be.Equal(t, res, false)
|
||||
be.Equal(t, conn.Out(), "0")
|
||||
|
||||
key, _ := db.Key().Get("age")
|
||||
testx.AssertEqual(t, key.Exists(), false)
|
||||
key, _ := red.Key().Get("age")
|
||||
be.Equal(t, key.Exists(), false)
|
||||
})
|
||||
}
|
||||
|
||||
@@ -5,8 +5,8 @@ import (
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"github.com/nalgeon/be"
|
||||
"github.com/nalgeon/redka/internal/redis"
|
||||
"github.com/nalgeon/redka/internal/testx"
|
||||
)
|
||||
|
||||
func TestExpireAtParse(t *testing.T) {
|
||||
@@ -55,12 +55,12 @@ func TestExpireAtParse(t *testing.T) {
|
||||
for _, test := range tests {
|
||||
t.Run(test.cmd, func(t *testing.T) {
|
||||
cmd, err := redis.Parse(parse, test.cmd)
|
||||
testx.AssertEqual(t, err, test.err)
|
||||
be.Equal(t, err, test.err)
|
||||
if err == nil {
|
||||
testx.AssertEqual(t, cmd.key, test.key)
|
||||
testx.AssertEqual(t, cmd.at.Unix(), test.at.Unix())
|
||||
be.Equal(t, cmd.key, test.key)
|
||||
be.Equal(t, cmd.at.Unix(), test.at.Unix())
|
||||
} else {
|
||||
testx.AssertEqual(t, cmd, ExpireAt{})
|
||||
be.Equal(t, cmd, ExpireAt{})
|
||||
}
|
||||
})
|
||||
}
|
||||
@@ -71,96 +71,86 @@ func TestExpireAtExec(t *testing.T) {
|
||||
return ParseExpireAt(b, 1000)
|
||||
}
|
||||
t.Run("create expireat", func(t *testing.T) {
|
||||
db, red := getDB(t)
|
||||
defer db.Close()
|
||||
|
||||
_ = db.Str().Set("name", "alice")
|
||||
red := getRedka(t)
|
||||
_ = red.Str().Set("name", "alice")
|
||||
|
||||
expireAt := time.Now().Add(60 * time.Second)
|
||||
cmd := redis.MustParse(parse, fmt.Sprintf("expireat name %d", expireAt.Unix()))
|
||||
conn := redis.NewFakeConn()
|
||||
res, err := cmd.Run(conn, red)
|
||||
testx.AssertNoErr(t, err)
|
||||
testx.AssertEqual(t, res, true)
|
||||
testx.AssertEqual(t, conn.Out(), "1")
|
||||
be.Err(t, err, nil)
|
||||
be.Equal(t, res, true)
|
||||
be.Equal(t, conn.Out(), "1")
|
||||
|
||||
key, _ := db.Key().Get("name")
|
||||
testx.AssertEqual(t, *key.ETime/1000, expireAt.UnixMilli()/1000)
|
||||
key, _ := red.Key().Get("name")
|
||||
be.Equal(t, *key.ETime/1000, expireAt.UnixMilli()/1000)
|
||||
})
|
||||
|
||||
t.Run("update expire", func(t *testing.T) {
|
||||
db, red := getDB(t)
|
||||
defer db.Close()
|
||||
|
||||
_ = db.Str().Set("name", "alice")
|
||||
red := getRedka(t)
|
||||
_ = red.Str().Set("name", "alice")
|
||||
|
||||
expireAt := time.Now()
|
||||
cmd := redis.MustParse(parse, fmt.Sprintf("expireat name %d", expireAt.Add(60*time.Second).Unix()))
|
||||
conn := redis.NewFakeConn()
|
||||
res, err := cmd.Run(conn, red)
|
||||
testx.AssertNoErr(t, err)
|
||||
testx.AssertEqual(t, res, true)
|
||||
testx.AssertEqual(t, conn.Out(), "1")
|
||||
be.Err(t, err, nil)
|
||||
be.Equal(t, res, true)
|
||||
be.Equal(t, conn.Out(), "1")
|
||||
|
||||
cmd = redis.MustParse(parse, fmt.Sprintf("expireat name %d", expireAt.Add(20*time.Second).Unix()))
|
||||
conn = redis.NewFakeConn()
|
||||
res, err = cmd.Run(conn, red)
|
||||
testx.AssertNoErr(t, err)
|
||||
testx.AssertEqual(t, res, true)
|
||||
testx.AssertEqual(t, conn.Out(), "1")
|
||||
be.Err(t, err, nil)
|
||||
be.Equal(t, res, true)
|
||||
be.Equal(t, conn.Out(), "1")
|
||||
|
||||
key, _ := db.Key().Get("name")
|
||||
testx.AssertEqual(t, *key.ETime/1000, expireAt.Add(20*time.Second).UnixMilli()/1000)
|
||||
key, _ := red.Key().Get("name")
|
||||
be.Equal(t, *key.ETime/1000, expireAt.Add(20*time.Second).UnixMilli()/1000)
|
||||
})
|
||||
|
||||
t.Run("set to zero", func(t *testing.T) {
|
||||
db, red := getDB(t)
|
||||
defer db.Close()
|
||||
|
||||
_ = db.Str().Set("name", "alice")
|
||||
red := getRedka(t)
|
||||
_ = red.Str().Set("name", "alice")
|
||||
|
||||
cmd := redis.MustParse(parse, "expireat name 0")
|
||||
conn := redis.NewFakeConn()
|
||||
res, err := cmd.Run(conn, red)
|
||||
testx.AssertNoErr(t, err)
|
||||
testx.AssertEqual(t, res, true)
|
||||
testx.AssertEqual(t, conn.Out(), "1")
|
||||
be.Err(t, err, nil)
|
||||
be.Equal(t, res, true)
|
||||
be.Equal(t, conn.Out(), "1")
|
||||
|
||||
key, _ := db.Key().Get("name")
|
||||
testx.AssertEqual(t, key.Exists(), false)
|
||||
key, _ := red.Key().Get("name")
|
||||
be.Equal(t, key.Exists(), false)
|
||||
})
|
||||
|
||||
t.Run("negative", func(t *testing.T) {
|
||||
db, red := getDB(t)
|
||||
defer db.Close()
|
||||
|
||||
_ = db.Str().Set("name", "alice")
|
||||
red := getRedka(t)
|
||||
_ = red.Str().Set("name", "alice")
|
||||
|
||||
cmd := redis.MustParse(parse, "expireat name -10")
|
||||
conn := redis.NewFakeConn()
|
||||
res, err := cmd.Run(conn, red)
|
||||
testx.AssertNoErr(t, err)
|
||||
testx.AssertEqual(t, res, true)
|
||||
testx.AssertEqual(t, conn.Out(), "1")
|
||||
be.Err(t, err, nil)
|
||||
be.Equal(t, res, true)
|
||||
be.Equal(t, conn.Out(), "1")
|
||||
|
||||
key, _ := db.Key().Get("name")
|
||||
testx.AssertEqual(t, key.Exists(), false)
|
||||
key, _ := red.Key().Get("name")
|
||||
be.Equal(t, key.Exists(), false)
|
||||
})
|
||||
|
||||
t.Run("not found", func(t *testing.T) {
|
||||
db, red := getDB(t)
|
||||
defer db.Close()
|
||||
|
||||
_ = db.Str().Set("name", "alice")
|
||||
red := getRedka(t)
|
||||
_ = red.Str().Set("name", "alice")
|
||||
|
||||
cmd := redis.MustParse(parse, "expireat age 1700000000")
|
||||
conn := redis.NewFakeConn()
|
||||
res, err := cmd.Run(conn, red)
|
||||
testx.AssertNoErr(t, err)
|
||||
testx.AssertEqual(t, res, false)
|
||||
testx.AssertEqual(t, conn.Out(), "0")
|
||||
be.Err(t, err, nil)
|
||||
be.Equal(t, res, false)
|
||||
be.Equal(t, conn.Out(), "0")
|
||||
|
||||
key, _ := db.Key().Get("age")
|
||||
testx.AssertEqual(t, key.Exists(), false)
|
||||
key, _ := red.Key().Get("age")
|
||||
be.Equal(t, key.Exists(), false)
|
||||
})
|
||||
}
|
||||
|
||||
@@ -3,8 +3,8 @@ package key
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/nalgeon/be"
|
||||
"github.com/nalgeon/redka/internal/redis"
|
||||
"github.com/nalgeon/redka/internal/testx"
|
||||
)
|
||||
|
||||
func TestFlushDBParse(t *testing.T) {
|
||||
@@ -29,9 +29,9 @@ func TestFlushDBParse(t *testing.T) {
|
||||
for _, test := range tests {
|
||||
t.Run(test.cmd, func(t *testing.T) {
|
||||
cmd, err := redis.Parse(ParseFlushDB, test.cmd)
|
||||
testx.AssertEqual(t, err, test.err)
|
||||
be.Equal(t, err, test.err)
|
||||
if err != nil {
|
||||
testx.AssertEqual(t, cmd, FlushDB{})
|
||||
be.Equal(t, cmd, FlushDB{})
|
||||
}
|
||||
})
|
||||
}
|
||||
@@ -39,35 +39,32 @@ func TestFlushDBParse(t *testing.T) {
|
||||
|
||||
func TestFlushDBExec(t *testing.T) {
|
||||
t.Run("full", func(t *testing.T) {
|
||||
db, red := getDB(t)
|
||||
defer db.Close()
|
||||
|
||||
_ = db.Str().Set("name", "alice")
|
||||
_ = db.Str().Set("age", 25)
|
||||
red := getRedka(t)
|
||||
_ = red.Str().Set("name", "alice")
|
||||
_ = red.Str().Set("age", 25)
|
||||
|
||||
cmd := redis.MustParse(ParseFlushDB, "flushdb")
|
||||
conn := redis.NewFakeConn()
|
||||
res, err := cmd.Run(conn, red)
|
||||
testx.AssertNoErr(t, err)
|
||||
testx.AssertEqual(t, res, true)
|
||||
testx.AssertEqual(t, conn.Out(), "OK")
|
||||
be.Err(t, err, nil)
|
||||
be.Equal(t, res, true)
|
||||
be.Equal(t, conn.Out(), "OK")
|
||||
|
||||
keys, _ := db.Key().Keys("*")
|
||||
testx.AssertEqual(t, len(keys), 0)
|
||||
keys, _ := red.Key().Keys("*")
|
||||
be.Equal(t, len(keys), 0)
|
||||
})
|
||||
|
||||
t.Run("empty", func(t *testing.T) {
|
||||
db, red := getDB(t)
|
||||
defer db.Close()
|
||||
red := getRedka(t)
|
||||
|
||||
cmd := redis.MustParse(ParseFlushDB, "flushdb")
|
||||
conn := redis.NewFakeConn()
|
||||
res, err := cmd.Run(conn, red)
|
||||
testx.AssertNoErr(t, err)
|
||||
testx.AssertEqual(t, res, true)
|
||||
testx.AssertEqual(t, conn.Out(), "OK")
|
||||
be.Err(t, err, nil)
|
||||
be.Equal(t, res, true)
|
||||
be.Equal(t, conn.Out(), "OK")
|
||||
|
||||
keys, _ := db.Key().Keys("*")
|
||||
testx.AssertEqual(t, len(keys), 0)
|
||||
keys, _ := red.Key().Keys("*")
|
||||
be.Equal(t, len(keys), 0)
|
||||
})
|
||||
}
|
||||
|
||||
@@ -3,15 +3,12 @@ package key
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/nalgeon/redka"
|
||||
"github.com/nalgeon/redka/internal/redis"
|
||||
"github.com/nalgeon/redka/internal/testx"
|
||||
)
|
||||
|
||||
func getDB(tb testing.TB) (*redka.DB, redis.Redka) {
|
||||
func getRedka(tb testing.TB) redis.Redka {
|
||||
tb.Helper()
|
||||
db, err := redka.Open("file:/data.db?vfs=memdb", nil)
|
||||
if err != nil {
|
||||
tb.Fatal(err)
|
||||
}
|
||||
return db, redis.RedkaDB(db)
|
||||
db := testx.OpenDB(tb)
|
||||
return redis.RedkaDB(db)
|
||||
}
|
||||
|
||||
@@ -3,9 +3,9 @@ package key
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/nalgeon/be"
|
||||
"github.com/nalgeon/redka/internal/core"
|
||||
"github.com/nalgeon/redka/internal/redis"
|
||||
"github.com/nalgeon/redka/internal/testx"
|
||||
)
|
||||
|
||||
func TestKeysParse(t *testing.T) {
|
||||
@@ -39,25 +39,24 @@ func TestKeysParse(t *testing.T) {
|
||||
for _, test := range tests {
|
||||
t.Run(test.cmd, func(t *testing.T) {
|
||||
cmd, err := redis.Parse(ParseKeys, test.cmd)
|
||||
testx.AssertEqual(t, err, test.err)
|
||||
be.Equal(t, err, test.err)
|
||||
if err == nil {
|
||||
testx.AssertEqual(t, cmd.pattern, test.want)
|
||||
be.Equal(t, cmd.pattern, test.want)
|
||||
} else {
|
||||
testx.AssertEqual(t, cmd, Keys{})
|
||||
be.Equal(t, cmd, Keys{})
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestKeysExec(t *testing.T) {
|
||||
db, red := getDB(t)
|
||||
defer db.Close()
|
||||
red := getRedka(t)
|
||||
|
||||
_ = db.Str().Set("k11", "11")
|
||||
_ = db.Str().Set("k12", "12")
|
||||
_ = db.Str().Set("k21", "21")
|
||||
_ = db.Str().Set("k22", "22")
|
||||
_ = db.Str().Set("k31", "31")
|
||||
_ = red.Str().Set("k11", "11")
|
||||
_ = red.Str().Set("k12", "12")
|
||||
_ = red.Str().Set("k21", "21")
|
||||
_ = red.Str().Set("k22", "22")
|
||||
_ = red.Str().Set("k31", "31")
|
||||
|
||||
tests := []struct {
|
||||
cmd string
|
||||
@@ -91,11 +90,11 @@ func TestKeysExec(t *testing.T) {
|
||||
conn := redis.NewFakeConn()
|
||||
cmd := redis.MustParse(ParseKeys, test.cmd)
|
||||
keys, err := cmd.Run(conn, red)
|
||||
testx.AssertNoErr(t, err)
|
||||
be.Err(t, err, nil)
|
||||
for i, key := range keys.([]core.Key) {
|
||||
testx.AssertEqual(t, key.Key, test.res[i])
|
||||
be.Equal(t, key.Key, test.res[i])
|
||||
}
|
||||
testx.AssertEqual(t, conn.Out(), test.out)
|
||||
be.Equal(t, conn.Out(), test.out)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
@@ -4,8 +4,8 @@ import (
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"github.com/nalgeon/be"
|
||||
"github.com/nalgeon/redka/internal/redis"
|
||||
"github.com/nalgeon/redka/internal/testx"
|
||||
)
|
||||
|
||||
func TestPersistParse(t *testing.T) {
|
||||
@@ -34,11 +34,11 @@ func TestPersistParse(t *testing.T) {
|
||||
for _, test := range tests {
|
||||
t.Run(test.cmd, func(t *testing.T) {
|
||||
cmd, err := redis.Parse(ParsePersist, test.cmd)
|
||||
testx.AssertEqual(t, err, test.err)
|
||||
be.Equal(t, err, test.err)
|
||||
if err == nil {
|
||||
testx.AssertEqual(t, cmd.key, test.key)
|
||||
be.Equal(t, cmd.key, test.key)
|
||||
} else {
|
||||
testx.AssertEqual(t, cmd, Persist{})
|
||||
be.Equal(t, cmd, Persist{})
|
||||
}
|
||||
})
|
||||
}
|
||||
@@ -46,53 +46,47 @@ func TestPersistParse(t *testing.T) {
|
||||
|
||||
func TestPersistExec(t *testing.T) {
|
||||
t.Run("persist to persist", func(t *testing.T) {
|
||||
db, red := getDB(t)
|
||||
defer db.Close()
|
||||
|
||||
_ = db.Str().Set("name", "alice")
|
||||
red := getRedka(t)
|
||||
_ = red.Str().Set("name", "alice")
|
||||
|
||||
cmd := redis.MustParse(ParsePersist, "persist name")
|
||||
conn := redis.NewFakeConn()
|
||||
res, err := cmd.Run(conn, red)
|
||||
testx.AssertNoErr(t, err)
|
||||
testx.AssertEqual(t, res, true)
|
||||
testx.AssertEqual(t, conn.Out(), "1")
|
||||
be.Err(t, err, nil)
|
||||
be.Equal(t, res, true)
|
||||
be.Equal(t, conn.Out(), "1")
|
||||
|
||||
key, _ := db.Key().Get("name")
|
||||
testx.AssertEqual(t, key.ETime, (*int64)(nil))
|
||||
key, _ := red.Key().Get("name")
|
||||
be.Equal(t, key.ETime, (*int64)(nil))
|
||||
})
|
||||
|
||||
t.Run("volatile to persist", func(t *testing.T) {
|
||||
db, red := getDB(t)
|
||||
defer db.Close()
|
||||
|
||||
_ = db.Str().SetExpires("name", "alice", 60*time.Second)
|
||||
red := getRedka(t)
|
||||
_ = red.Str().SetExpires("name", "alice", 60*time.Second)
|
||||
|
||||
cmd := redis.MustParse(ParsePersist, "persist name")
|
||||
conn := redis.NewFakeConn()
|
||||
res, err := cmd.Run(conn, red)
|
||||
testx.AssertNoErr(t, err)
|
||||
testx.AssertEqual(t, res, true)
|
||||
testx.AssertEqual(t, conn.Out(), "1")
|
||||
be.Err(t, err, nil)
|
||||
be.Equal(t, res, true)
|
||||
be.Equal(t, conn.Out(), "1")
|
||||
|
||||
key, _ := db.Key().Get("name")
|
||||
testx.AssertEqual(t, key.ETime, (*int64)(nil))
|
||||
key, _ := red.Key().Get("name")
|
||||
be.Equal(t, key.ETime, (*int64)(nil))
|
||||
})
|
||||
|
||||
t.Run("not found", func(t *testing.T) {
|
||||
db, red := getDB(t)
|
||||
defer db.Close()
|
||||
|
||||
_ = db.Str().Set("name", "alice")
|
||||
red := getRedka(t)
|
||||
_ = red.Str().Set("name", "alice")
|
||||
|
||||
cmd := redis.MustParse(ParsePersist, "persist age")
|
||||
conn := redis.NewFakeConn()
|
||||
res, err := cmd.Run(conn, red)
|
||||
testx.AssertNoErr(t, err)
|
||||
testx.AssertEqual(t, res, false)
|
||||
testx.AssertEqual(t, conn.Out(), "0")
|
||||
be.Err(t, err, nil)
|
||||
be.Equal(t, res, false)
|
||||
be.Equal(t, conn.Out(), "0")
|
||||
|
||||
key, _ := db.Key().Get("age")
|
||||
testx.AssertEqual(t, key.Exists(), false)
|
||||
key, _ := red.Key().Get("age")
|
||||
be.Equal(t, key.Exists(), false)
|
||||
})
|
||||
}
|
||||
|
||||
@@ -4,8 +4,8 @@ import (
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"github.com/nalgeon/be"
|
||||
"github.com/nalgeon/redka/internal/redis"
|
||||
"github.com/nalgeon/redka/internal/testx"
|
||||
)
|
||||
|
||||
func TestPExpireParse(t *testing.T) {
|
||||
@@ -54,12 +54,12 @@ func TestPExpireParse(t *testing.T) {
|
||||
for _, test := range tests {
|
||||
t.Run(test.cmd, func(t *testing.T) {
|
||||
cmd, err := redis.Parse(parse, test.cmd)
|
||||
testx.AssertEqual(t, err, test.err)
|
||||
be.Equal(t, err, test.err)
|
||||
if err == nil {
|
||||
testx.AssertEqual(t, cmd.key, test.key)
|
||||
testx.AssertEqual(t, cmd.ttl, test.ttl)
|
||||
be.Equal(t, cmd.key, test.key)
|
||||
be.Equal(t, cmd.ttl, test.ttl)
|
||||
} else {
|
||||
testx.AssertEqual(t, cmd, Expire{})
|
||||
be.Equal(t, cmd, Expire{})
|
||||
}
|
||||
})
|
||||
}
|
||||
@@ -71,84 +71,79 @@ func TestPExpireExec(t *testing.T) {
|
||||
}
|
||||
|
||||
t.Run("create pexpire", func(t *testing.T) {
|
||||
db, red := getDB(t)
|
||||
defer db.Close()
|
||||
_ = db.Str().Set("name", "alice")
|
||||
red := getRedka(t)
|
||||
_ = red.Str().Set("name", "alice")
|
||||
|
||||
cmd := redis.MustParse(parse, "pexpire name 60000")
|
||||
conn := redis.NewFakeConn()
|
||||
res, err := cmd.Run(conn, red)
|
||||
testx.AssertNoErr(t, err)
|
||||
testx.AssertEqual(t, res, true)
|
||||
testx.AssertEqual(t, conn.Out(), "1")
|
||||
be.Err(t, err, nil)
|
||||
be.Equal(t, res, true)
|
||||
be.Equal(t, conn.Out(), "1")
|
||||
|
||||
expireAt := time.Now().Add(60 * time.Second)
|
||||
key, _ := db.Key().Get("name")
|
||||
testx.AssertEqual(t, *key.ETime/1000, expireAt.UnixMilli()/1000)
|
||||
key, _ := red.Key().Get("name")
|
||||
be.Equal(t, *key.ETime/1000, expireAt.UnixMilli()/1000)
|
||||
})
|
||||
|
||||
t.Run("update pexpire", func(t *testing.T) {
|
||||
db, red := getDB(t)
|
||||
defer db.Close()
|
||||
_ = db.Str().SetExpires("name", "alice", 60*time.Second)
|
||||
red := getRedka(t)
|
||||
_ = red.Str().SetExpires("name", "alice", 60*time.Second)
|
||||
|
||||
cmd := redis.MustParse(parse, "pexpire name 30000")
|
||||
conn := redis.NewFakeConn()
|
||||
res, err := cmd.Run(conn, red)
|
||||
testx.AssertNoErr(t, err)
|
||||
testx.AssertEqual(t, res, true)
|
||||
testx.AssertEqual(t, conn.Out(), "1")
|
||||
be.Err(t, err, nil)
|
||||
be.Equal(t, res, true)
|
||||
be.Equal(t, conn.Out(), "1")
|
||||
|
||||
expireAt := time.Now().Add(30 * time.Second)
|
||||
key, _ := db.Key().Get("name")
|
||||
testx.AssertEqual(t, *key.ETime/1000, expireAt.UnixMilli()/1000)
|
||||
key, _ := red.Key().Get("name")
|
||||
be.Equal(t, *key.ETime/1000, expireAt.UnixMilli()/1000)
|
||||
})
|
||||
|
||||
t.Run("set to zero", func(t *testing.T) {
|
||||
db, red := getDB(t)
|
||||
defer db.Close()
|
||||
_ = db.Str().Set("name", "alice")
|
||||
red := getRedka(t)
|
||||
_ = red.Str().Set("name", "alice")
|
||||
|
||||
cmd := redis.MustParse(parse, "pexpire name 0")
|
||||
conn := redis.NewFakeConn()
|
||||
res, err := cmd.Run(conn, red)
|
||||
testx.AssertNoErr(t, err)
|
||||
testx.AssertEqual(t, res, true)
|
||||
testx.AssertEqual(t, conn.Out(), "1")
|
||||
be.Err(t, err, nil)
|
||||
be.Equal(t, res, true)
|
||||
be.Equal(t, conn.Out(), "1")
|
||||
|
||||
key, _ := db.Key().Get("name")
|
||||
testx.AssertEqual(t, key.Exists(), false)
|
||||
key, _ := red.Key().Get("name")
|
||||
be.Equal(t, key.Exists(), false)
|
||||
})
|
||||
|
||||
t.Run("negative", func(t *testing.T) {
|
||||
db, red := getDB(t)
|
||||
defer db.Close()
|
||||
_ = db.Str().Set("name", "alice")
|
||||
red := getRedka(t)
|
||||
_ = red.Str().Set("name", "alice")
|
||||
|
||||
cmd := redis.MustParse(parse, "pexpire name -1000")
|
||||
conn := redis.NewFakeConn()
|
||||
res, err := cmd.Run(conn, red)
|
||||
testx.AssertNoErr(t, err)
|
||||
testx.AssertEqual(t, res, true)
|
||||
testx.AssertEqual(t, conn.Out(), "1")
|
||||
be.Err(t, err, nil)
|
||||
be.Equal(t, res, true)
|
||||
be.Equal(t, conn.Out(), "1")
|
||||
|
||||
key, _ := db.Key().Get("name")
|
||||
testx.AssertEqual(t, key.Exists(), false)
|
||||
key, _ := red.Key().Get("name")
|
||||
be.Equal(t, key.Exists(), false)
|
||||
})
|
||||
|
||||
t.Run("not found", func(t *testing.T) {
|
||||
db, red := getDB(t)
|
||||
defer db.Close()
|
||||
_ = db.Str().Set("name", "alice")
|
||||
red := getRedka(t)
|
||||
_ = red.Str().Set("name", "alice")
|
||||
|
||||
cmd := redis.MustParse(parse, "pexpire age 1000")
|
||||
conn := redis.NewFakeConn()
|
||||
res, err := cmd.Run(conn, red)
|
||||
testx.AssertNoErr(t, err)
|
||||
testx.AssertEqual(t, res, false)
|
||||
testx.AssertEqual(t, conn.Out(), "0")
|
||||
be.Err(t, err, nil)
|
||||
be.Equal(t, res, false)
|
||||
be.Equal(t, conn.Out(), "0")
|
||||
|
||||
key, _ := db.Key().Get("age")
|
||||
testx.AssertEqual(t, key.Exists(), false)
|
||||
key, _ := red.Key().Get("age")
|
||||
be.Equal(t, key.Exists(), false)
|
||||
})
|
||||
}
|
||||
|
||||
@@ -4,9 +4,9 @@ import (
|
||||
"slices"
|
||||
"testing"
|
||||
|
||||
"github.com/nalgeon/be"
|
||||
"github.com/nalgeon/redka/internal/core"
|
||||
"github.com/nalgeon/redka/internal/redis"
|
||||
"github.com/nalgeon/redka/internal/testx"
|
||||
)
|
||||
|
||||
func TestRandomKeyParse(t *testing.T) {
|
||||
@@ -31,9 +31,9 @@ func TestRandomKeyParse(t *testing.T) {
|
||||
for _, test := range tests {
|
||||
t.Run(test.cmd, func(t *testing.T) {
|
||||
cmd, err := redis.Parse(ParseRandomKey, test.cmd)
|
||||
testx.AssertEqual(t, err, test.err)
|
||||
be.Equal(t, err, test.err)
|
||||
if err != nil {
|
||||
testx.AssertEqual(t, cmd, RandomKey{})
|
||||
be.Equal(t, cmd, RandomKey{})
|
||||
}
|
||||
})
|
||||
}
|
||||
@@ -41,28 +41,26 @@ func TestRandomKeyParse(t *testing.T) {
|
||||
|
||||
func TestRandomKeyExec(t *testing.T) {
|
||||
t.Run("found", func(t *testing.T) {
|
||||
db, red := getDB(t)
|
||||
defer db.Close()
|
||||
_ = db.Str().Set("name", "alice")
|
||||
_ = db.Str().Set("age", 25)
|
||||
_ = db.Str().Set("city", "paris")
|
||||
keys := []string{"name", "age", "city"}
|
||||
red := getRedka(t)
|
||||
_ = red.Str().Set("name", "alice")
|
||||
_ = red.Str().Set("age", 25)
|
||||
_ = red.Str().Set("city", "paris")
|
||||
|
||||
conn := redis.NewFakeConn()
|
||||
cmd := redis.MustParse(ParseRandomKey, "randomkey")
|
||||
res, err := cmd.Run(conn, red)
|
||||
testx.AssertNoErr(t, err)
|
||||
testx.AssertEqual(t, slices.Contains(keys, res.(core.Key).Key), true)
|
||||
testx.AssertEqual(t, slices.Contains(keys, conn.Out()), true)
|
||||
be.Err(t, err, nil)
|
||||
keys := []string{"name", "age", "city"}
|
||||
be.True(t, slices.Contains(keys, res.(core.Key).Key))
|
||||
be.True(t, slices.Contains(keys, conn.Out()))
|
||||
})
|
||||
t.Run("not found", func(t *testing.T) {
|
||||
db, red := getDB(t)
|
||||
defer db.Close()
|
||||
red := getRedka(t)
|
||||
conn := redis.NewFakeConn()
|
||||
cmd := redis.MustParse(ParseRandomKey, "randomkey")
|
||||
res, err := cmd.Run(conn, red)
|
||||
testx.AssertNoErr(t, err)
|
||||
testx.AssertEqual(t, res, nil)
|
||||
testx.AssertEqual(t, conn.Out(), "(nil)")
|
||||
be.Err(t, err, nil)
|
||||
be.Equal(t, res, nil)
|
||||
be.Equal(t, conn.Out(), "(nil)")
|
||||
})
|
||||
}
|
||||
|
||||
@@ -3,9 +3,9 @@ package key
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/nalgeon/be"
|
||||
"github.com/nalgeon/redka/internal/core"
|
||||
"github.com/nalgeon/redka/internal/redis"
|
||||
"github.com/nalgeon/redka/internal/testx"
|
||||
)
|
||||
|
||||
func TestRenameParse(t *testing.T) {
|
||||
@@ -38,12 +38,12 @@ func TestRenameParse(t *testing.T) {
|
||||
for _, test := range tests {
|
||||
t.Run(test.cmd, func(t *testing.T) {
|
||||
cmd, err := redis.Parse(ParseRename, test.cmd)
|
||||
testx.AssertEqual(t, err, test.err)
|
||||
be.Equal(t, err, test.err)
|
||||
if err == nil {
|
||||
testx.AssertEqual(t, cmd.key, test.key)
|
||||
testx.AssertEqual(t, cmd.newKey, test.newKey)
|
||||
be.Equal(t, cmd.key, test.key)
|
||||
be.Equal(t, cmd.newKey, test.newKey)
|
||||
} else {
|
||||
testx.AssertEqual(t, cmd, Rename{})
|
||||
be.Equal(t, cmd, Rename{})
|
||||
}
|
||||
})
|
||||
}
|
||||
@@ -51,83 +51,75 @@ func TestRenameParse(t *testing.T) {
|
||||
|
||||
func TestRenameExec(t *testing.T) {
|
||||
t.Run("create new", func(t *testing.T) {
|
||||
db, red := getDB(t)
|
||||
defer db.Close()
|
||||
|
||||
_ = db.Str().Set("name", "alice")
|
||||
red := getRedka(t)
|
||||
_ = red.Str().Set("name", "alice")
|
||||
|
||||
cmd := redis.MustParse(ParseRename, "rename name title")
|
||||
conn := redis.NewFakeConn()
|
||||
res, err := cmd.Run(conn, red)
|
||||
testx.AssertNoErr(t, err)
|
||||
testx.AssertEqual(t, res, true)
|
||||
testx.AssertEqual(t, conn.Out(), "OK")
|
||||
be.Err(t, err, nil)
|
||||
be.Equal(t, res, true)
|
||||
be.Equal(t, conn.Out(), "OK")
|
||||
|
||||
key, _ := db.Key().Get("name")
|
||||
testx.AssertEqual(t, key.Exists(), false)
|
||||
key, _ = db.Key().Get("title")
|
||||
testx.AssertEqual(t, key.Exists(), true)
|
||||
key, _ := red.Key().Get("name")
|
||||
be.Equal(t, key.Exists(), false)
|
||||
key, _ = red.Key().Get("title")
|
||||
be.Equal(t, key.Exists(), true)
|
||||
})
|
||||
|
||||
t.Run("replace existing", func(t *testing.T) {
|
||||
db, red := getDB(t)
|
||||
defer db.Close()
|
||||
|
||||
_ = db.Str().Set("name", "alice")
|
||||
_ = db.Str().Set("title", "bob")
|
||||
red := getRedka(t)
|
||||
_ = red.Str().Set("name", "alice")
|
||||
_ = red.Str().Set("title", "bob")
|
||||
|
||||
cmd := redis.MustParse(ParseRename, "rename name title")
|
||||
conn := redis.NewFakeConn()
|
||||
res, err := cmd.Run(conn, red)
|
||||
testx.AssertNoErr(t, err)
|
||||
testx.AssertEqual(t, res, true)
|
||||
testx.AssertEqual(t, conn.Out(), "OK")
|
||||
be.Err(t, err, nil)
|
||||
be.Equal(t, res, true)
|
||||
be.Equal(t, conn.Out(), "OK")
|
||||
|
||||
key, _ := db.Key().Get("name")
|
||||
testx.AssertEqual(t, key.Exists(), false)
|
||||
key, _ = db.Key().Get("title")
|
||||
testx.AssertEqual(t, key.Exists(), true)
|
||||
val, _ := db.Str().Get("title")
|
||||
testx.AssertEqual(t, val.String(), "alice")
|
||||
key, _ := red.Key().Get("name")
|
||||
be.Equal(t, key.Exists(), false)
|
||||
key, _ = red.Key().Get("title")
|
||||
be.Equal(t, key.Exists(), true)
|
||||
val, _ := red.Str().Get("title")
|
||||
be.Equal(t, val.String(), "alice")
|
||||
})
|
||||
|
||||
t.Run("rename to self", func(t *testing.T) {
|
||||
db, red := getDB(t)
|
||||
defer db.Close()
|
||||
|
||||
_ = db.Str().Set("name", "alice")
|
||||
red := getRedka(t)
|
||||
_ = red.Str().Set("name", "alice")
|
||||
|
||||
cmd := redis.MustParse(ParseRename, "rename name name")
|
||||
conn := redis.NewFakeConn()
|
||||
res, err := cmd.Run(conn, red)
|
||||
testx.AssertNoErr(t, err)
|
||||
testx.AssertEqual(t, res, true)
|
||||
testx.AssertEqual(t, conn.Out(), "OK")
|
||||
be.Err(t, err, nil)
|
||||
be.Equal(t, res, true)
|
||||
be.Equal(t, conn.Out(), "OK")
|
||||
|
||||
key, _ := db.Key().Get("name")
|
||||
testx.AssertEqual(t, key.Exists(), true)
|
||||
val, _ := db.Str().Get("name")
|
||||
testx.AssertEqual(t, val.String(), "alice")
|
||||
key, _ := red.Key().Get("name")
|
||||
be.Equal(t, key.Exists(), true)
|
||||
val, _ := red.Str().Get("name")
|
||||
be.Equal(t, val.String(), "alice")
|
||||
})
|
||||
|
||||
t.Run("not found", func(t *testing.T) {
|
||||
db, red := getDB(t)
|
||||
defer db.Close()
|
||||
|
||||
_ = db.Str().Set("title", "bob")
|
||||
red := getRedka(t)
|
||||
_ = red.Str().Set("title", "bob")
|
||||
|
||||
cmd := redis.MustParse(ParseRename, "rename name title")
|
||||
conn := redis.NewFakeConn()
|
||||
res, err := cmd.Run(conn, red)
|
||||
testx.AssertEqual(t, err, core.ErrNotFound)
|
||||
testx.AssertEqual(t, res, nil)
|
||||
testx.AssertEqual(t, conn.Out(), redis.ErrNotFound.Error()+" (rename)")
|
||||
be.Equal(t, err, core.ErrNotFound)
|
||||
be.Equal(t, res, nil)
|
||||
be.Equal(t, conn.Out(), redis.ErrNotFound.Error()+" (rename)")
|
||||
|
||||
key, _ := db.Key().Get("name")
|
||||
testx.AssertEqual(t, key.Exists(), false)
|
||||
key, _ = db.Key().Get("title")
|
||||
testx.AssertEqual(t, key.Exists(), true)
|
||||
val, _ := db.Str().Get("title")
|
||||
testx.AssertEqual(t, val.String(), "bob")
|
||||
key, _ := red.Key().Get("name")
|
||||
be.Equal(t, key.Exists(), false)
|
||||
key, _ = red.Key().Get("title")
|
||||
be.Equal(t, key.Exists(), true)
|
||||
val, _ := red.Str().Get("title")
|
||||
be.Equal(t, val.String(), "bob")
|
||||
})
|
||||
}
|
||||
|
||||
@@ -3,9 +3,9 @@ package key
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/nalgeon/be"
|
||||
"github.com/nalgeon/redka/internal/core"
|
||||
"github.com/nalgeon/redka/internal/redis"
|
||||
"github.com/nalgeon/redka/internal/testx"
|
||||
)
|
||||
|
||||
func TestRenameNXParse(t *testing.T) {
|
||||
@@ -38,12 +38,12 @@ func TestRenameNXParse(t *testing.T) {
|
||||
for _, test := range tests {
|
||||
t.Run(test.cmd, func(t *testing.T) {
|
||||
cmd, err := redis.Parse(ParseRenameNX, test.cmd)
|
||||
testx.AssertEqual(t, err, test.err)
|
||||
be.Equal(t, err, test.err)
|
||||
if err == nil {
|
||||
testx.AssertEqual(t, cmd.key, test.key)
|
||||
testx.AssertEqual(t, cmd.newKey, test.newKey)
|
||||
be.Equal(t, cmd.key, test.key)
|
||||
be.Equal(t, cmd.newKey, test.newKey)
|
||||
} else {
|
||||
testx.AssertEqual(t, cmd, RenameNX{})
|
||||
be.Equal(t, cmd, RenameNX{})
|
||||
}
|
||||
})
|
||||
}
|
||||
@@ -51,85 +51,77 @@ func TestRenameNXParse(t *testing.T) {
|
||||
|
||||
func TestRenameNXExec(t *testing.T) {
|
||||
t.Run("create new", func(t *testing.T) {
|
||||
db, red := getDB(t)
|
||||
defer db.Close()
|
||||
|
||||
_ = db.Str().Set("name", "alice")
|
||||
red := getRedka(t)
|
||||
_ = red.Str().Set("name", "alice")
|
||||
|
||||
cmd := redis.MustParse(ParseRenameNX, "renamenx name title")
|
||||
conn := redis.NewFakeConn()
|
||||
res, err := cmd.Run(conn, red)
|
||||
testx.AssertNoErr(t, err)
|
||||
testx.AssertEqual(t, res, true)
|
||||
testx.AssertEqual(t, conn.Out(), "1")
|
||||
be.Err(t, err, nil)
|
||||
be.Equal(t, res, true)
|
||||
be.Equal(t, conn.Out(), "1")
|
||||
|
||||
key, _ := db.Key().Get("name")
|
||||
testx.AssertEqual(t, key.Exists(), false)
|
||||
key, _ = db.Key().Get("title")
|
||||
testx.AssertEqual(t, key.Exists(), true)
|
||||
key, _ := red.Key().Get("name")
|
||||
be.Equal(t, key.Exists(), false)
|
||||
key, _ = red.Key().Get("title")
|
||||
be.Equal(t, key.Exists(), true)
|
||||
})
|
||||
|
||||
t.Run("replace existing", func(t *testing.T) {
|
||||
db, red := getDB(t)
|
||||
defer db.Close()
|
||||
|
||||
_ = db.Str().Set("name", "alice")
|
||||
_ = db.Str().Set("title", "bob")
|
||||
red := getRedka(t)
|
||||
_ = red.Str().Set("name", "alice")
|
||||
_ = red.Str().Set("title", "bob")
|
||||
|
||||
cmd := redis.MustParse(ParseRenameNX, "renamenx name title")
|
||||
conn := redis.NewFakeConn()
|
||||
res, err := cmd.Run(conn, red)
|
||||
testx.AssertNoErr(t, err)
|
||||
testx.AssertEqual(t, res, false)
|
||||
testx.AssertEqual(t, conn.Out(), "0")
|
||||
be.Err(t, err, nil)
|
||||
be.Equal(t, res, false)
|
||||
be.Equal(t, conn.Out(), "0")
|
||||
|
||||
key, _ := db.Key().Get("name")
|
||||
testx.AssertEqual(t, key.Exists(), true)
|
||||
val, _ := db.Str().Get("name")
|
||||
testx.AssertEqual(t, val.String(), "alice")
|
||||
key, _ = db.Key().Get("title")
|
||||
testx.AssertEqual(t, key.Exists(), true)
|
||||
val, _ = db.Str().Get("title")
|
||||
testx.AssertEqual(t, val.String(), "bob")
|
||||
key, _ := red.Key().Get("name")
|
||||
be.Equal(t, key.Exists(), true)
|
||||
val, _ := red.Str().Get("name")
|
||||
be.Equal(t, val.String(), "alice")
|
||||
key, _ = red.Key().Get("title")
|
||||
be.Equal(t, key.Exists(), true)
|
||||
val, _ = red.Str().Get("title")
|
||||
be.Equal(t, val.String(), "bob")
|
||||
})
|
||||
|
||||
t.Run("rename to self", func(t *testing.T) {
|
||||
db, red := getDB(t)
|
||||
defer db.Close()
|
||||
|
||||
_ = db.Str().Set("name", "alice")
|
||||
red := getRedka(t)
|
||||
_ = red.Str().Set("name", "alice")
|
||||
|
||||
cmd := redis.MustParse(ParseRenameNX, "renamenx name name")
|
||||
conn := redis.NewFakeConn()
|
||||
res, err := cmd.Run(conn, red)
|
||||
testx.AssertNoErr(t, err)
|
||||
testx.AssertEqual(t, res, false)
|
||||
testx.AssertEqual(t, conn.Out(), "0")
|
||||
be.Err(t, err, nil)
|
||||
be.Equal(t, res, false)
|
||||
be.Equal(t, conn.Out(), "0")
|
||||
|
||||
key, _ := db.Key().Get("name")
|
||||
testx.AssertEqual(t, key.Exists(), true)
|
||||
val, _ := db.Str().Get("name")
|
||||
testx.AssertEqual(t, val.String(), "alice")
|
||||
key, _ := red.Key().Get("name")
|
||||
be.Equal(t, key.Exists(), true)
|
||||
val, _ := red.Str().Get("name")
|
||||
be.Equal(t, val.String(), "alice")
|
||||
})
|
||||
|
||||
t.Run("not found", func(t *testing.T) {
|
||||
db, red := getDB(t)
|
||||
defer db.Close()
|
||||
|
||||
_ = db.Str().Set("title", "bob")
|
||||
red := getRedka(t)
|
||||
_ = red.Str().Set("title", "bob")
|
||||
|
||||
cmd := redis.MustParse(ParseRenameNX, "renamenx name title")
|
||||
conn := redis.NewFakeConn()
|
||||
res, err := cmd.Run(conn, red)
|
||||
testx.AssertEqual(t, err, core.ErrNotFound)
|
||||
testx.AssertEqual(t, res, nil)
|
||||
testx.AssertEqual(t, conn.Out(), redis.ErrNotFound.Error()+" (renamenx)")
|
||||
be.Equal(t, err, core.ErrNotFound)
|
||||
be.Equal(t, res, nil)
|
||||
be.Equal(t, conn.Out(), redis.ErrNotFound.Error()+" (renamenx)")
|
||||
|
||||
key, _ := db.Key().Get("name")
|
||||
testx.AssertEqual(t, key.Exists(), false)
|
||||
key, _ = db.Key().Get("title")
|
||||
testx.AssertEqual(t, key.Exists(), true)
|
||||
val, _ := db.Str().Get("title")
|
||||
testx.AssertEqual(t, val.String(), "bob")
|
||||
key, _ := red.Key().Get("name")
|
||||
be.Equal(t, key.Exists(), false)
|
||||
key, _ = red.Key().Get("title")
|
||||
be.Equal(t, key.Exists(), true)
|
||||
val, _ := red.Str().Get("title")
|
||||
be.Equal(t, val.String(), "bob")
|
||||
})
|
||||
}
|
||||
|
||||
@@ -1,11 +1,12 @@
|
||||
package key
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"testing"
|
||||
|
||||
"github.com/nalgeon/be"
|
||||
"github.com/nalgeon/redka/internal/redis"
|
||||
"github.com/nalgeon/redka/internal/rkey"
|
||||
"github.com/nalgeon/redka/internal/testx"
|
||||
)
|
||||
|
||||
func TestScanParse(t *testing.T) {
|
||||
@@ -108,14 +109,14 @@ func TestScanParse(t *testing.T) {
|
||||
for _, test := range tests {
|
||||
t.Run(test.cmd, func(t *testing.T) {
|
||||
cmd, err := redis.Parse(ParseScan, test.cmd)
|
||||
testx.AssertEqual(t, err, test.err)
|
||||
be.Equal(t, err, test.err)
|
||||
if err == nil {
|
||||
testx.AssertEqual(t, cmd.cursor, test.cursor)
|
||||
testx.AssertEqual(t, cmd.match, test.match)
|
||||
testx.AssertEqual(t, cmd.ktype, test.ktype)
|
||||
testx.AssertEqual(t, cmd.count, test.count)
|
||||
be.Equal(t, cmd.cursor, test.cursor)
|
||||
be.Equal(t, cmd.match, test.match)
|
||||
be.Equal(t, cmd.ktype, test.ktype)
|
||||
be.Equal(t, cmd.count, test.count)
|
||||
} else {
|
||||
testx.AssertEqual(t, cmd, Scan{})
|
||||
be.Equal(t, cmd, Scan{})
|
||||
}
|
||||
})
|
||||
}
|
||||
@@ -123,152 +124,164 @@ func TestScanParse(t *testing.T) {
|
||||
|
||||
func TestScanExec(t *testing.T) {
|
||||
t.Run("scan all", func(t *testing.T) {
|
||||
db, red := getDB(t)
|
||||
defer db.Close()
|
||||
red := getRedka(t)
|
||||
|
||||
_ = db.Str().Set("k11", "11")
|
||||
_ = db.Str().Set("k12", "12")
|
||||
_ = db.Str().Set("k21", "21")
|
||||
_ = db.Str().Set("k22", "22")
|
||||
_ = db.Str().Set("k31", "31")
|
||||
_ = red.Str().Set("k11", "11")
|
||||
_ = red.Str().Set("k12", "12")
|
||||
_ = red.Str().Set("k21", "21")
|
||||
_ = red.Str().Set("k22", "22")
|
||||
_ = red.Str().Set("k31", "31")
|
||||
|
||||
var cursor int
|
||||
{
|
||||
cmd := redis.MustParse(ParseScan, "scan 0")
|
||||
conn := redis.NewFakeConn()
|
||||
|
||||
res, err := cmd.Run(conn, red)
|
||||
testx.AssertNoErr(t, err)
|
||||
be.Err(t, err, nil)
|
||||
|
||||
sres := res.(rkey.ScanResult)
|
||||
testx.AssertEqual(t, sres.Cursor, 5)
|
||||
testx.AssertEqual(t, len(sres.Keys), 5)
|
||||
testx.AssertEqual(t, sres.Keys[0].Key, "k11")
|
||||
testx.AssertEqual(t, sres.Keys[4].Key, "k31")
|
||||
testx.AssertEqual(t, conn.Out(), "2,5,5,k11,k12,k21,k22,k31")
|
||||
be.True(t, sres.Cursor > 0)
|
||||
be.Equal(t, len(sres.Keys), 5)
|
||||
be.Equal(t, sres.Keys[0].Key, "k11")
|
||||
be.Equal(t, sres.Keys[4].Key, "k31")
|
||||
wantOut := fmt.Sprintf("2,%d,5,k11,k12,k21,k22,k31", sres.Cursor)
|
||||
be.Equal(t, conn.Out(), wantOut)
|
||||
cursor = sres.Cursor
|
||||
}
|
||||
{
|
||||
cmd := redis.MustParse(ParseScan, "scan 5")
|
||||
next := fmt.Sprintf("scan %d", cursor)
|
||||
cmd := redis.MustParse(ParseScan, next)
|
||||
conn := redis.NewFakeConn()
|
||||
|
||||
res, err := cmd.Run(conn, red)
|
||||
testx.AssertNoErr(t, err)
|
||||
be.Err(t, err, nil)
|
||||
|
||||
sres := res.(rkey.ScanResult)
|
||||
testx.AssertEqual(t, sres.Cursor, 0)
|
||||
testx.AssertEqual(t, len(sres.Keys), 0)
|
||||
testx.AssertEqual(t, conn.Out(), "2,0,0")
|
||||
be.Equal(t, sres.Cursor, 0)
|
||||
be.Equal(t, len(sres.Keys), 0)
|
||||
be.Equal(t, conn.Out(), "2,0,0")
|
||||
}
|
||||
})
|
||||
t.Run("scan pattern", func(t *testing.T) {
|
||||
db, red := getDB(t)
|
||||
defer db.Close()
|
||||
red := getRedka(t)
|
||||
|
||||
_ = db.Str().Set("k11", "11")
|
||||
_ = db.Str().Set("k12", "12")
|
||||
_ = db.Str().Set("k21", "21")
|
||||
_ = db.Str().Set("k22", "22")
|
||||
_ = db.Str().Set("k31", "31")
|
||||
_ = red.Str().Set("k11", "11")
|
||||
_ = red.Str().Set("k12", "12")
|
||||
_ = red.Str().Set("k21", "21")
|
||||
_ = red.Str().Set("k22", "22")
|
||||
_ = red.Str().Set("k31", "31")
|
||||
|
||||
cmd := redis.MustParse(ParseScan, "scan 0 match k2*")
|
||||
conn := redis.NewFakeConn()
|
||||
|
||||
res, err := cmd.Run(conn, red)
|
||||
testx.AssertNoErr(t, err)
|
||||
be.Err(t, err, nil)
|
||||
|
||||
sres := res.(rkey.ScanResult)
|
||||
testx.AssertEqual(t, sres.Cursor, 4)
|
||||
testx.AssertEqual(t, len(sres.Keys), 2)
|
||||
testx.AssertEqual(t, sres.Keys[0].Key, "k21")
|
||||
testx.AssertEqual(t, sres.Keys[1].Key, "k22")
|
||||
testx.AssertEqual(t, conn.Out(), "2,4,2,k21,k22")
|
||||
be.True(t, sres.Cursor > 0)
|
||||
be.Equal(t, len(sres.Keys), 2)
|
||||
be.Equal(t, sres.Keys[0].Key, "k21")
|
||||
be.Equal(t, sres.Keys[1].Key, "k22")
|
||||
wantOut := fmt.Sprintf("2,%d,2,k21,k22", sres.Cursor)
|
||||
be.Equal(t, conn.Out(), wantOut)
|
||||
})
|
||||
t.Run("scan type", func(t *testing.T) {
|
||||
db, red := getDB(t)
|
||||
defer db.Close()
|
||||
red := getRedka(t)
|
||||
|
||||
_ = db.Str().Set("t1", "str")
|
||||
_, _ = db.List().PushBack("t2", "elem")
|
||||
_, _ = db.Hash().Set("t4", "field", "value")
|
||||
_, _ = db.ZSet().Add("t5", "elem", 11)
|
||||
_ = red.Str().Set("t1", "str")
|
||||
_, _ = red.List().PushBack("t2", "elem")
|
||||
_, _ = red.Hash().Set("t4", "field", "value")
|
||||
_, _ = red.ZSet().Add("t5", "elem", 11)
|
||||
|
||||
cmd := redis.MustParse(ParseScan, "scan 0 match t* type hash")
|
||||
conn := redis.NewFakeConn()
|
||||
|
||||
res, err := cmd.Run(conn, red)
|
||||
testx.AssertNoErr(t, err)
|
||||
be.Err(t, err, nil)
|
||||
|
||||
sres := res.(rkey.ScanResult)
|
||||
testx.AssertEqual(t, sres.Cursor, 3)
|
||||
testx.AssertEqual(t, len(sres.Keys), 1)
|
||||
testx.AssertEqual(t, sres.Keys[0].Key, "t4")
|
||||
testx.AssertEqual(t, conn.Out(), "2,3,1,t4")
|
||||
be.True(t, sres.Cursor > 0)
|
||||
be.Equal(t, len(sres.Keys), 1)
|
||||
be.Equal(t, sres.Keys[0].Key, "t4")
|
||||
wantOut := fmt.Sprintf("2,%d,1,t4", sres.Cursor)
|
||||
be.Equal(t, conn.Out(), wantOut)
|
||||
})
|
||||
t.Run("scan count", func(t *testing.T) {
|
||||
db, red := getDB(t)
|
||||
defer db.Close()
|
||||
red := getRedka(t)
|
||||
|
||||
_ = db.Str().Set("k11", "11")
|
||||
_ = db.Str().Set("k12", "12")
|
||||
_ = db.Str().Set("k21", "21")
|
||||
_ = db.Str().Set("k22", "22")
|
||||
_ = db.Str().Set("k31", "31")
|
||||
_ = red.Str().Set("k11", "11")
|
||||
_ = red.Str().Set("k12", "12")
|
||||
_ = red.Str().Set("k21", "21")
|
||||
_ = red.Str().Set("k22", "22")
|
||||
_ = red.Str().Set("k31", "31")
|
||||
|
||||
var cursor int
|
||||
{
|
||||
// page 1
|
||||
cmd := redis.MustParse(ParseScan, "scan 0 match * count 2")
|
||||
conn := redis.NewFakeConn()
|
||||
|
||||
res, err := cmd.Run(conn, red)
|
||||
testx.AssertNoErr(t, err)
|
||||
be.Err(t, err, nil)
|
||||
|
||||
sres := res.(rkey.ScanResult)
|
||||
testx.AssertEqual(t, sres.Cursor, 2)
|
||||
testx.AssertEqual(t, len(sres.Keys), 2)
|
||||
testx.AssertEqual(t, sres.Keys[0].Key, "k11")
|
||||
testx.AssertEqual(t, sres.Keys[1].Key, "k12")
|
||||
testx.AssertEqual(t, conn.Out(), "2,2,2,k11,k12")
|
||||
be.True(t, sres.Cursor > cursor)
|
||||
be.Equal(t, len(sres.Keys), 2)
|
||||
be.Equal(t, sres.Keys[0].Key, "k11")
|
||||
be.Equal(t, sres.Keys[1].Key, "k12")
|
||||
wantOut := fmt.Sprintf("2,%d,2,k11,k12", sres.Cursor)
|
||||
be.Equal(t, conn.Out(), wantOut)
|
||||
cursor = sres.Cursor
|
||||
}
|
||||
{
|
||||
// page 2
|
||||
cmd := redis.MustParse(ParseScan, "scan 2 match * count 2")
|
||||
next := fmt.Sprintf("scan %d match * count 2", cursor)
|
||||
cmd := redis.MustParse(ParseScan, next)
|
||||
conn := redis.NewFakeConn()
|
||||
|
||||
res, err := cmd.Run(conn, red)
|
||||
testx.AssertNoErr(t, err)
|
||||
be.Err(t, err, nil)
|
||||
|
||||
sres := res.(rkey.ScanResult)
|
||||
testx.AssertEqual(t, sres.Cursor, 4)
|
||||
testx.AssertEqual(t, len(sres.Keys), 2)
|
||||
testx.AssertEqual(t, sres.Keys[0].Key, "k21")
|
||||
testx.AssertEqual(t, sres.Keys[1].Key, "k22")
|
||||
testx.AssertEqual(t, conn.Out(), "2,4,2,k21,k22")
|
||||
be.True(t, sres.Cursor > cursor)
|
||||
be.Equal(t, len(sres.Keys), 2)
|
||||
be.Equal(t, sres.Keys[0].Key, "k21")
|
||||
be.Equal(t, sres.Keys[1].Key, "k22")
|
||||
wantOut := fmt.Sprintf("2,%d,2,k21,k22", sres.Cursor)
|
||||
be.Equal(t, conn.Out(), wantOut)
|
||||
cursor = sres.Cursor
|
||||
}
|
||||
{
|
||||
// page 3
|
||||
cmd := redis.MustParse(ParseScan, "scan 4 match * count 2")
|
||||
next := fmt.Sprintf("scan %d match * count 2", cursor)
|
||||
cmd := redis.MustParse(ParseScan, next)
|
||||
conn := redis.NewFakeConn()
|
||||
|
||||
res, err := cmd.Run(conn, red)
|
||||
testx.AssertNoErr(t, err)
|
||||
be.Err(t, err, nil)
|
||||
|
||||
sres := res.(rkey.ScanResult)
|
||||
testx.AssertEqual(t, sres.Cursor, 5)
|
||||
testx.AssertEqual(t, len(sres.Keys), 1)
|
||||
testx.AssertEqual(t, sres.Keys[0].Key, "k31")
|
||||
testx.AssertEqual(t, conn.Out(), "2,5,1,k31")
|
||||
be.True(t, sres.Cursor > cursor)
|
||||
be.Equal(t, len(sres.Keys), 1)
|
||||
be.Equal(t, sres.Keys[0].Key, "k31")
|
||||
wantOut := fmt.Sprintf("2,%d,1,k31", sres.Cursor)
|
||||
be.Equal(t, conn.Out(), wantOut)
|
||||
cursor = sres.Cursor
|
||||
}
|
||||
{
|
||||
// no more pages
|
||||
cmd := redis.MustParse(ParseScan, "scan 5 match * count 2")
|
||||
next := fmt.Sprintf("scan %d match * count 2", cursor)
|
||||
cmd := redis.MustParse(ParseScan, next)
|
||||
conn := redis.NewFakeConn()
|
||||
|
||||
res, err := cmd.Run(conn, red)
|
||||
testx.AssertNoErr(t, err)
|
||||
be.Err(t, err, nil)
|
||||
|
||||
sres := res.(rkey.ScanResult)
|
||||
testx.AssertEqual(t, sres.Cursor, 0)
|
||||
testx.AssertEqual(t, len(sres.Keys), 0)
|
||||
testx.AssertEqual(t, conn.Out(), "2,0,0")
|
||||
be.Equal(t, sres.Cursor, 0)
|
||||
be.Equal(t, len(sres.Keys), 0)
|
||||
be.Equal(t, conn.Out(), "2,0,0")
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
@@ -4,8 +4,8 @@ import (
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"github.com/nalgeon/be"
|
||||
"github.com/nalgeon/redka/internal/redis"
|
||||
"github.com/nalgeon/redka/internal/testx"
|
||||
)
|
||||
|
||||
func TestTTLParse(t *testing.T) {
|
||||
@@ -34,11 +34,11 @@ func TestTTLParse(t *testing.T) {
|
||||
for _, test := range tests {
|
||||
t.Run(test.cmd, func(t *testing.T) {
|
||||
cmd, err := redis.Parse(ParseTTL, test.cmd)
|
||||
testx.AssertEqual(t, err, test.err)
|
||||
be.Equal(t, err, test.err)
|
||||
if err == nil {
|
||||
testx.AssertEqual(t, cmd.key, test.key)
|
||||
be.Equal(t, cmd.key, test.key)
|
||||
} else {
|
||||
testx.AssertEqual(t, cmd, TTL{})
|
||||
be.Equal(t, cmd, TTL{})
|
||||
}
|
||||
})
|
||||
}
|
||||
@@ -46,42 +46,37 @@ func TestTTLParse(t *testing.T) {
|
||||
|
||||
func TestTTLExec(t *testing.T) {
|
||||
t.Run("has ttl", func(t *testing.T) {
|
||||
db, red := getDB(t)
|
||||
defer db.Close()
|
||||
|
||||
_ = db.Str().SetExpires("name", "alice", 60*time.Second)
|
||||
red := getRedka(t)
|
||||
_ = red.Str().SetExpires("name", "alice", 60*time.Second)
|
||||
|
||||
cmd := redis.MustParse(ParseTTL, "ttl name")
|
||||
conn := redis.NewFakeConn()
|
||||
res, err := cmd.Run(conn, red)
|
||||
testx.AssertNoErr(t, err)
|
||||
testx.AssertEqual(t, res, 60)
|
||||
testx.AssertEqual(t, conn.Out(), "60")
|
||||
be.Err(t, err, nil)
|
||||
be.Equal(t, res, 60)
|
||||
be.Equal(t, conn.Out(), "60")
|
||||
})
|
||||
|
||||
t.Run("no ttl", func(t *testing.T) {
|
||||
db, red := getDB(t)
|
||||
defer db.Close()
|
||||
|
||||
_ = db.Str().Set("name", "alice")
|
||||
red := getRedka(t)
|
||||
_ = red.Str().Set("name", "alice")
|
||||
|
||||
cmd := redis.MustParse(ParseTTL, "ttl name")
|
||||
conn := redis.NewFakeConn()
|
||||
res, err := cmd.Run(conn, red)
|
||||
testx.AssertNoErr(t, err)
|
||||
testx.AssertEqual(t, res, -1)
|
||||
testx.AssertEqual(t, conn.Out(), "-1")
|
||||
be.Err(t, err, nil)
|
||||
be.Equal(t, res, -1)
|
||||
be.Equal(t, conn.Out(), "-1")
|
||||
})
|
||||
|
||||
t.Run("not found", func(t *testing.T) {
|
||||
db, red := getDB(t)
|
||||
defer db.Close()
|
||||
red := getRedka(t)
|
||||
|
||||
cmd := redis.MustParse(ParseTTL, "ttl name")
|
||||
conn := redis.NewFakeConn()
|
||||
res, err := cmd.Run(conn, red)
|
||||
testx.AssertNoErr(t, err)
|
||||
testx.AssertEqual(t, res, -2)
|
||||
testx.AssertEqual(t, conn.Out(), "-2")
|
||||
be.Err(t, err, nil)
|
||||
be.Equal(t, res, -2)
|
||||
be.Equal(t, conn.Out(), "-2")
|
||||
})
|
||||
}
|
||||
|
||||
@@ -3,8 +3,8 @@ package key
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/nalgeon/be"
|
||||
"github.com/nalgeon/redka/internal/redis"
|
||||
"github.com/nalgeon/redka/internal/testx"
|
||||
)
|
||||
|
||||
func TestTypeParse(t *testing.T) {
|
||||
@@ -33,24 +33,23 @@ func TestTypeParse(t *testing.T) {
|
||||
for _, test := range tests {
|
||||
t.Run(test.cmd, func(t *testing.T) {
|
||||
cmd, err := redis.Parse(ParseType, test.cmd)
|
||||
testx.AssertEqual(t, err, test.err)
|
||||
be.Equal(t, err, test.err)
|
||||
if err == nil {
|
||||
testx.AssertEqual(t, cmd.key, test.key)
|
||||
be.Equal(t, cmd.key, test.key)
|
||||
} else {
|
||||
testx.AssertEqual(t, cmd, Type{})
|
||||
be.Equal(t, cmd, Type{})
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestTypeExec(t *testing.T) {
|
||||
db, red := getDB(t)
|
||||
defer db.Close()
|
||||
red := getRedka(t)
|
||||
|
||||
_ = db.Str().Set("kstr", "string")
|
||||
_, _ = db.List().PushBack("klist", "list")
|
||||
_, _ = db.Hash().Set("khash", "field", "hash")
|
||||
_, _ = db.ZSet().Add("kzset", "zset", 1)
|
||||
_ = red.Str().Set("kstr", "string")
|
||||
_, _ = red.List().PushBack("klist", "list")
|
||||
_, _ = red.Hash().Set("khash", "field", "hash")
|
||||
_, _ = red.ZSet().Add("kzset", "zset", 1)
|
||||
|
||||
tests := []struct {
|
||||
key string
|
||||
@@ -68,9 +67,9 @@ func TestTypeExec(t *testing.T) {
|
||||
cmd := redis.MustParse(ParseType, "type "+test.key)
|
||||
conn := redis.NewFakeConn()
|
||||
res, err := cmd.Run(conn, red)
|
||||
testx.AssertNoErr(t, err)
|
||||
testx.AssertEqual(t, res, test.want)
|
||||
testx.AssertEqual(t, conn.Out(), test.want)
|
||||
be.Err(t, err, nil)
|
||||
be.Equal(t, res.(string), test.want)
|
||||
be.Equal(t, conn.Out(), test.want)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3,9 +3,9 @@ package list
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/nalgeon/be"
|
||||
"github.com/nalgeon/redka/internal/core"
|
||||
"github.com/nalgeon/redka/internal/redis"
|
||||
"github.com/nalgeon/redka/internal/testx"
|
||||
)
|
||||
|
||||
func TestLIndexParse(t *testing.T) {
|
||||
@@ -39,12 +39,12 @@ func TestLIndexParse(t *testing.T) {
|
||||
for _, test := range tests {
|
||||
t.Run(test.cmd, func(t *testing.T) {
|
||||
cmd, err := redis.Parse(ParseLIndex, test.cmd)
|
||||
testx.AssertEqual(t, err, test.err)
|
||||
be.Equal(t, err, test.err)
|
||||
if err == nil {
|
||||
testx.AssertEqual(t, cmd.key, test.want.key)
|
||||
testx.AssertEqual(t, cmd.index, test.want.index)
|
||||
be.Equal(t, cmd.key, test.want.key)
|
||||
be.Equal(t, cmd.index, test.want.index)
|
||||
} else {
|
||||
testx.AssertEqual(t, cmd, test.want)
|
||||
be.Equal(t, cmd, test.want)
|
||||
}
|
||||
})
|
||||
}
|
||||
@@ -52,78 +52,72 @@ func TestLIndexParse(t *testing.T) {
|
||||
|
||||
func TestLIndexExec(t *testing.T) {
|
||||
t.Run("empty list", func(t *testing.T) {
|
||||
db, red := getDB(t)
|
||||
defer db.Close()
|
||||
red := getRedka(t)
|
||||
|
||||
cmd := redis.MustParse(ParseLIndex, "lindex key 0")
|
||||
conn := redis.NewFakeConn()
|
||||
res, err := cmd.Run(conn, red)
|
||||
testx.AssertNoErr(t, err)
|
||||
testx.AssertEqual(t, res, core.Value(nil))
|
||||
testx.AssertEqual(t, conn.Out(), "(nil)")
|
||||
be.Err(t, err, nil)
|
||||
be.Equal(t, res.(core.Value), core.Value(nil))
|
||||
be.Equal(t, conn.Out(), "(nil)")
|
||||
})
|
||||
t.Run("single elem", func(t *testing.T) {
|
||||
db, red := getDB(t)
|
||||
defer db.Close()
|
||||
_, _ = db.List().PushBack("key", "elem")
|
||||
red := getRedka(t)
|
||||
_, _ = red.List().PushBack("key", "elem")
|
||||
|
||||
cmd := redis.MustParse(ParseLIndex, "lindex key 0")
|
||||
conn := redis.NewFakeConn()
|
||||
res, err := cmd.Run(conn, red)
|
||||
testx.AssertNoErr(t, err)
|
||||
testx.AssertEqual(t, res, core.Value("elem"))
|
||||
testx.AssertEqual(t, conn.Out(), "elem")
|
||||
be.Err(t, err, nil)
|
||||
be.Equal(t, res.(core.Value), core.Value("elem"))
|
||||
be.Equal(t, conn.Out(), "elem")
|
||||
})
|
||||
t.Run("multiple elems", func(t *testing.T) {
|
||||
db, red := getDB(t)
|
||||
defer db.Close()
|
||||
_, _ = db.List().PushBack("key", "one")
|
||||
_, _ = db.List().PushBack("key", "two")
|
||||
_, _ = db.List().PushBack("key", "thr")
|
||||
red := getRedka(t)
|
||||
_, _ = red.List().PushBack("key", "one")
|
||||
_, _ = red.List().PushBack("key", "two")
|
||||
_, _ = red.List().PushBack("key", "thr")
|
||||
|
||||
cmd := redis.MustParse(ParseLIndex, "lindex key 1")
|
||||
conn := redis.NewFakeConn()
|
||||
res, err := cmd.Run(conn, red)
|
||||
testx.AssertNoErr(t, err)
|
||||
testx.AssertEqual(t, res, core.Value("two"))
|
||||
testx.AssertEqual(t, conn.Out(), "two")
|
||||
be.Err(t, err, nil)
|
||||
be.Equal(t, res.(core.Value), core.Value("two"))
|
||||
be.Equal(t, conn.Out(), "two")
|
||||
})
|
||||
t.Run("list index out of bounds", func(t *testing.T) {
|
||||
db, red := getDB(t)
|
||||
defer db.Close()
|
||||
_, _ = db.List().PushBack("key", "elem")
|
||||
red := getRedka(t)
|
||||
_, _ = red.List().PushBack("key", "elem")
|
||||
|
||||
cmd := redis.MustParse(ParseLIndex, "lindex key 1")
|
||||
conn := redis.NewFakeConn()
|
||||
res, err := cmd.Run(conn, red)
|
||||
testx.AssertNoErr(t, err)
|
||||
testx.AssertEqual(t, res, core.Value(nil))
|
||||
testx.AssertEqual(t, conn.Out(), "(nil)")
|
||||
be.Err(t, err, nil)
|
||||
be.Equal(t, res.(core.Value), core.Value(nil))
|
||||
be.Equal(t, conn.Out(), "(nil)")
|
||||
})
|
||||
t.Run("negative index", func(t *testing.T) {
|
||||
db, red := getDB(t)
|
||||
defer db.Close()
|
||||
_, _ = db.List().PushBack("key", "one")
|
||||
_, _ = db.List().PushBack("key", "two")
|
||||
_, _ = db.List().PushBack("key", "thr")
|
||||
red := getRedka(t)
|
||||
_, _ = red.List().PushBack("key", "one")
|
||||
_, _ = red.List().PushBack("key", "two")
|
||||
_, _ = red.List().PushBack("key", "thr")
|
||||
|
||||
cmd := redis.MustParse(ParseLIndex, "lindex key -2")
|
||||
conn := redis.NewFakeConn()
|
||||
res, err := cmd.Run(conn, red)
|
||||
testx.AssertNoErr(t, err)
|
||||
testx.AssertEqual(t, res, core.Value("two"))
|
||||
testx.AssertEqual(t, conn.Out(), "two")
|
||||
be.Err(t, err, nil)
|
||||
be.Equal(t, res.(core.Value), core.Value("two"))
|
||||
be.Equal(t, conn.Out(), "two")
|
||||
})
|
||||
t.Run("key type mismatch", func(t *testing.T) {
|
||||
db, red := getDB(t)
|
||||
defer db.Close()
|
||||
_ = db.Str().Set("key", "str")
|
||||
red := getRedka(t)
|
||||
_ = red.Str().Set("key", "str")
|
||||
|
||||
cmd := redis.MustParse(ParseLIndex, "lindex key 0")
|
||||
conn := redis.NewFakeConn()
|
||||
res, err := cmd.Run(conn, red)
|
||||
testx.AssertNoErr(t, err)
|
||||
testx.AssertEqual(t, res, core.Value(nil))
|
||||
testx.AssertEqual(t, conn.Out(), "(nil)")
|
||||
be.Err(t, err, nil)
|
||||
be.Equal(t, res.(core.Value), core.Value(nil))
|
||||
be.Equal(t, conn.Out(), "(nil)")
|
||||
})
|
||||
}
|
||||
|
||||
@@ -3,9 +3,9 @@ package list
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/nalgeon/be"
|
||||
"github.com/nalgeon/redka/internal/core"
|
||||
"github.com/nalgeon/redka/internal/redis"
|
||||
"github.com/nalgeon/redka/internal/testx"
|
||||
)
|
||||
|
||||
func TestLInsertParse(t *testing.T) {
|
||||
@@ -55,14 +55,14 @@ func TestLInsertParse(t *testing.T) {
|
||||
for _, test := range tests {
|
||||
t.Run(test.cmd, func(t *testing.T) {
|
||||
cmd, err := redis.Parse(ParseLInsert, test.cmd)
|
||||
testx.AssertEqual(t, err, test.err)
|
||||
be.Equal(t, err, test.err)
|
||||
if err == nil {
|
||||
testx.AssertEqual(t, cmd.key, test.want.key)
|
||||
testx.AssertEqual(t, cmd.where, test.want.where)
|
||||
testx.AssertEqual(t, cmd.pivot, test.want.pivot)
|
||||
testx.AssertEqual(t, cmd.elem, test.want.elem)
|
||||
be.Equal(t, cmd.key, test.want.key)
|
||||
be.Equal(t, cmd.where, test.want.where)
|
||||
be.Equal(t, cmd.pivot, test.want.pivot)
|
||||
be.Equal(t, cmd.elem, test.want.elem)
|
||||
} else {
|
||||
testx.AssertEqual(t, cmd, test.want)
|
||||
be.Equal(t, cmd, test.want)
|
||||
}
|
||||
})
|
||||
}
|
||||
@@ -70,90 +70,84 @@ func TestLInsertParse(t *testing.T) {
|
||||
|
||||
func TestLInsertExec(t *testing.T) {
|
||||
t.Run("empty list", func(t *testing.T) {
|
||||
db, red := getDB(t)
|
||||
defer db.Close()
|
||||
red := getRedka(t)
|
||||
|
||||
cmd := redis.MustParse(ParseLInsert, "linsert key before pivot elem")
|
||||
conn := redis.NewFakeConn()
|
||||
res, err := cmd.Run(conn, red)
|
||||
testx.AssertNoErr(t, err)
|
||||
testx.AssertEqual(t, res, 0)
|
||||
testx.AssertEqual(t, conn.Out(), "0")
|
||||
be.Err(t, err, nil)
|
||||
be.Equal(t, res, 0)
|
||||
be.Equal(t, conn.Out(), "0")
|
||||
|
||||
_, err = db.List().Get("key", 0)
|
||||
testx.AssertEqual(t, err, core.ErrNotFound)
|
||||
_, err = red.List().Get("key", 0)
|
||||
be.Equal(t, err, core.ErrNotFound)
|
||||
})
|
||||
t.Run("insert before first", func(t *testing.T) {
|
||||
db, red := getDB(t)
|
||||
defer db.Close()
|
||||
_, err := db.List().PushBack("key", "pivot")
|
||||
testx.AssertNoErr(t, err)
|
||||
red := getRedka(t)
|
||||
_, err := red.List().PushBack("key", "pivot")
|
||||
be.Err(t, err, nil)
|
||||
|
||||
cmd := redis.MustParse(ParseLInsert, "linsert key before pivot elem")
|
||||
conn := redis.NewFakeConn()
|
||||
res, err := cmd.Run(conn, red)
|
||||
testx.AssertNoErr(t, err)
|
||||
testx.AssertEqual(t, res, 2)
|
||||
testx.AssertEqual(t, conn.Out(), "2")
|
||||
be.Err(t, err, nil)
|
||||
be.Equal(t, res, 2)
|
||||
be.Equal(t, conn.Out(), "2")
|
||||
|
||||
elem, _ := db.List().Get("key", 0)
|
||||
testx.AssertEqual(t, elem, core.Value("elem"))
|
||||
elem, _ := red.List().Get("key", 0)
|
||||
be.Equal(t, elem, core.Value("elem"))
|
||||
})
|
||||
t.Run("insert before middle", func(t *testing.T) {
|
||||
db, red := getDB(t)
|
||||
defer db.Close()
|
||||
_, _ = db.List().PushBack("key", "one")
|
||||
_, _ = db.List().PushBack("key", "thr")
|
||||
red := getRedka(t)
|
||||
_, _ = red.List().PushBack("key", "one")
|
||||
_, _ = red.List().PushBack("key", "thr")
|
||||
|
||||
cmd := redis.MustParse(ParseLInsert, "linsert key before thr two")
|
||||
conn := redis.NewFakeConn()
|
||||
res, err := cmd.Run(conn, red)
|
||||
testx.AssertNoErr(t, err)
|
||||
testx.AssertEqual(t, res, 3)
|
||||
testx.AssertEqual(t, conn.Out(), "3")
|
||||
be.Err(t, err, nil)
|
||||
be.Equal(t, res, 3)
|
||||
be.Equal(t, conn.Out(), "3")
|
||||
|
||||
elem, _ := db.List().Get("key", 1)
|
||||
testx.AssertEqual(t, elem, core.Value("two"))
|
||||
elem, _ := red.List().Get("key", 1)
|
||||
be.Equal(t, elem, core.Value("two"))
|
||||
})
|
||||
t.Run("insert after middle", func(t *testing.T) {
|
||||
db, red := getDB(t)
|
||||
defer db.Close()
|
||||
_, _ = db.List().PushBack("key", "one")
|
||||
_, _ = db.List().PushBack("key", "thr")
|
||||
red := getRedka(t)
|
||||
_, _ = red.List().PushBack("key", "one")
|
||||
_, _ = red.List().PushBack("key", "thr")
|
||||
|
||||
cmd := redis.MustParse(ParseLInsert, "linsert key after thr two")
|
||||
conn := redis.NewFakeConn()
|
||||
res, err := cmd.Run(conn, red)
|
||||
testx.AssertNoErr(t, err)
|
||||
testx.AssertEqual(t, res, 3)
|
||||
testx.AssertEqual(t, conn.Out(), "3")
|
||||
be.Err(t, err, nil)
|
||||
be.Equal(t, res, 3)
|
||||
be.Equal(t, conn.Out(), "3")
|
||||
|
||||
elem, _ := db.List().Get("key", 2)
|
||||
testx.AssertEqual(t, elem, core.Value("two"))
|
||||
elem, _ := red.List().Get("key", 2)
|
||||
be.Equal(t, elem, core.Value("two"))
|
||||
})
|
||||
t.Run("elem not found", func(t *testing.T) {
|
||||
db, red := getDB(t)
|
||||
defer db.Close()
|
||||
_, _ = db.List().PushBack("key", "one")
|
||||
_, _ = db.List().PushBack("key", "two")
|
||||
red := getRedka(t)
|
||||
_, _ = red.List().PushBack("key", "one")
|
||||
_, _ = red.List().PushBack("key", "two")
|
||||
|
||||
cmd := redis.MustParse(ParseLInsert, "linsert key before thr two")
|
||||
conn := redis.NewFakeConn()
|
||||
res, err := cmd.Run(conn, red)
|
||||
testx.AssertNoErr(t, err)
|
||||
testx.AssertEqual(t, res, -1)
|
||||
testx.AssertEqual(t, conn.Out(), "-1")
|
||||
be.Err(t, err, nil)
|
||||
be.Equal(t, res, -1)
|
||||
be.Equal(t, conn.Out(), "-1")
|
||||
})
|
||||
t.Run("key type mismatch", func(t *testing.T) {
|
||||
db, red := getDB(t)
|
||||
defer db.Close()
|
||||
_ = db.Str().Set("key", "str")
|
||||
red := getRedka(t)
|
||||
_ = red.Str().Set("key", "str")
|
||||
|
||||
cmd := redis.MustParse(ParseLInsert, "linsert key before pivot elem")
|
||||
conn := redis.NewFakeConn()
|
||||
res, err := cmd.Run(conn, red)
|
||||
testx.AssertNoErr(t, err)
|
||||
testx.AssertEqual(t, res, 0)
|
||||
testx.AssertEqual(t, conn.Out(), "0")
|
||||
be.Err(t, err, nil)
|
||||
be.Equal(t, res, 0)
|
||||
be.Equal(t, conn.Out(), "0")
|
||||
})
|
||||
}
|
||||
|
||||
@@ -3,15 +3,12 @@ package list
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/nalgeon/redka"
|
||||
"github.com/nalgeon/redka/internal/redis"
|
||||
"github.com/nalgeon/redka/internal/testx"
|
||||
)
|
||||
|
||||
func getDB(tb testing.TB) (*redka.DB, redis.Redka) {
|
||||
func getRedka(tb testing.TB) redis.Redka {
|
||||
tb.Helper()
|
||||
db, err := redka.Open("file:/data.db?vfs=memdb", nil)
|
||||
if err != nil {
|
||||
tb.Fatal(err)
|
||||
}
|
||||
return db, redis.RedkaDB(db)
|
||||
db := testx.OpenDB(tb)
|
||||
return redis.RedkaDB(db)
|
||||
}
|
||||
|
||||
@@ -3,8 +3,8 @@ package list
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/nalgeon/be"
|
||||
"github.com/nalgeon/redka/internal/redis"
|
||||
"github.com/nalgeon/redka/internal/testx"
|
||||
)
|
||||
|
||||
func TestLLenParse(t *testing.T) {
|
||||
@@ -33,11 +33,11 @@ func TestLLenParse(t *testing.T) {
|
||||
for _, test := range tests {
|
||||
t.Run(test.cmd, func(t *testing.T) {
|
||||
cmd, err := redis.Parse(ParseLLen, test.cmd)
|
||||
testx.AssertEqual(t, err, test.err)
|
||||
be.Equal(t, err, test.err)
|
||||
if err == nil {
|
||||
testx.AssertEqual(t, cmd.key, test.want.key)
|
||||
be.Equal(t, cmd.key, test.want.key)
|
||||
} else {
|
||||
testx.AssertEqual(t, cmd, test.want)
|
||||
be.Equal(t, cmd, test.want)
|
||||
}
|
||||
})
|
||||
}
|
||||
@@ -45,52 +45,48 @@ func TestLLenParse(t *testing.T) {
|
||||
|
||||
func TestLLenExec(t *testing.T) {
|
||||
t.Run("empty list", func(t *testing.T) {
|
||||
db, red := getDB(t)
|
||||
defer db.Close()
|
||||
red := getRedka(t)
|
||||
|
||||
cmd := redis.MustParse(ParseLLen, "llen key")
|
||||
conn := redis.NewFakeConn()
|
||||
res, err := cmd.Run(conn, red)
|
||||
testx.AssertNoErr(t, err)
|
||||
testx.AssertEqual(t, res, 0)
|
||||
testx.AssertEqual(t, conn.Out(), "0")
|
||||
be.Err(t, err, nil)
|
||||
be.Equal(t, res, 0)
|
||||
be.Equal(t, conn.Out(), "0")
|
||||
})
|
||||
t.Run("single elem", func(t *testing.T) {
|
||||
db, red := getDB(t)
|
||||
defer db.Close()
|
||||
_, _ = db.List().PushBack("key", "elem")
|
||||
red := getRedka(t)
|
||||
_, _ = red.List().PushBack("key", "elem")
|
||||
|
||||
cmd := redis.MustParse(ParseLLen, "llen key")
|
||||
conn := redis.NewFakeConn()
|
||||
res, err := cmd.Run(conn, red)
|
||||
testx.AssertNoErr(t, err)
|
||||
testx.AssertEqual(t, res, 1)
|
||||
testx.AssertEqual(t, conn.Out(), "1")
|
||||
be.Err(t, err, nil)
|
||||
be.Equal(t, res, 1)
|
||||
be.Equal(t, conn.Out(), "1")
|
||||
})
|
||||
t.Run("multiple elems", func(t *testing.T) {
|
||||
db, red := getDB(t)
|
||||
defer db.Close()
|
||||
_, _ = db.List().PushBack("key", "one")
|
||||
_, _ = db.List().PushBack("key", "two")
|
||||
_, _ = db.List().PushBack("key", "thr")
|
||||
red := getRedka(t)
|
||||
_, _ = red.List().PushBack("key", "one")
|
||||
_, _ = red.List().PushBack("key", "two")
|
||||
_, _ = red.List().PushBack("key", "thr")
|
||||
|
||||
cmd := redis.MustParse(ParseLLen, "llen key")
|
||||
conn := redis.NewFakeConn()
|
||||
res, err := cmd.Run(conn, red)
|
||||
testx.AssertNoErr(t, err)
|
||||
testx.AssertEqual(t, res, 3)
|
||||
testx.AssertEqual(t, conn.Out(), "3")
|
||||
be.Err(t, err, nil)
|
||||
be.Equal(t, res, 3)
|
||||
be.Equal(t, conn.Out(), "3")
|
||||
})
|
||||
t.Run("key type mismatch", func(t *testing.T) {
|
||||
db, red := getDB(t)
|
||||
defer db.Close()
|
||||
_ = db.Str().Set("key", "str")
|
||||
red := getRedka(t)
|
||||
_ = red.Str().Set("key", "str")
|
||||
|
||||
cmd := redis.MustParse(ParseLLen, "llen key")
|
||||
conn := redis.NewFakeConn()
|
||||
res, err := cmd.Run(conn, red)
|
||||
testx.AssertNoErr(t, err)
|
||||
testx.AssertEqual(t, res, 0)
|
||||
testx.AssertEqual(t, conn.Out(), "0")
|
||||
be.Err(t, err, nil)
|
||||
be.Equal(t, res, 0)
|
||||
be.Equal(t, conn.Out(), "0")
|
||||
})
|
||||
}
|
||||
|
||||
@@ -3,9 +3,9 @@ package list
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/nalgeon/be"
|
||||
"github.com/nalgeon/redka/internal/core"
|
||||
"github.com/nalgeon/redka/internal/redis"
|
||||
"github.com/nalgeon/redka/internal/testx"
|
||||
)
|
||||
|
||||
func TestLPopParse(t *testing.T) {
|
||||
@@ -34,11 +34,11 @@ func TestLPopParse(t *testing.T) {
|
||||
for _, test := range tests {
|
||||
t.Run(test.cmd, func(t *testing.T) {
|
||||
cmd, err := redis.Parse(ParseLPop, test.cmd)
|
||||
testx.AssertEqual(t, err, test.err)
|
||||
be.Equal(t, err, test.err)
|
||||
if err == nil {
|
||||
testx.AssertEqual(t, cmd.key, test.want.key)
|
||||
be.Equal(t, cmd.key, test.want.key)
|
||||
} else {
|
||||
testx.AssertEqual(t, cmd, test.want)
|
||||
be.Equal(t, cmd, test.want)
|
||||
}
|
||||
})
|
||||
}
|
||||
@@ -46,62 +46,58 @@ func TestLPopParse(t *testing.T) {
|
||||
|
||||
func TestLPopExec(t *testing.T) {
|
||||
t.Run("empty list", func(t *testing.T) {
|
||||
db, red := getDB(t)
|
||||
defer db.Close()
|
||||
red := getRedka(t)
|
||||
|
||||
cmd := redis.MustParse(ParseLPop, "lpop key")
|
||||
conn := redis.NewFakeConn()
|
||||
res, err := cmd.Run(conn, red)
|
||||
testx.AssertNoErr(t, err)
|
||||
testx.AssertEqual(t, res, core.Value(nil))
|
||||
testx.AssertEqual(t, conn.Out(), "(nil)")
|
||||
be.Err(t, err, nil)
|
||||
be.Equal(t, res.(core.Value), core.Value(nil))
|
||||
be.Equal(t, conn.Out(), "(nil)")
|
||||
})
|
||||
t.Run("pop elem", func(t *testing.T) {
|
||||
db, red := getDB(t)
|
||||
defer db.Close()
|
||||
_, _ = db.List().PushBack("key", "elem")
|
||||
red := getRedka(t)
|
||||
_, _ = red.List().PushBack("key", "elem")
|
||||
|
||||
cmd := redis.MustParse(ParseLPop, "lpop key")
|
||||
conn := redis.NewFakeConn()
|
||||
res, err := cmd.Run(conn, red)
|
||||
testx.AssertNoErr(t, err)
|
||||
testx.AssertEqual(t, res, core.Value("elem"))
|
||||
testx.AssertEqual(t, conn.Out(), "elem")
|
||||
be.Err(t, err, nil)
|
||||
be.Equal(t, res.(core.Value), core.Value("elem"))
|
||||
be.Equal(t, conn.Out(), "elem")
|
||||
})
|
||||
t.Run("pop multiple", func(t *testing.T) {
|
||||
db, red := getDB(t)
|
||||
defer db.Close()
|
||||
_, _ = db.List().PushBack("key", "one")
|
||||
_, _ = db.List().PushBack("key", "two")
|
||||
_, _ = db.List().PushBack("key", "thr")
|
||||
red := getRedka(t)
|
||||
_, _ = red.List().PushBack("key", "one")
|
||||
_, _ = red.List().PushBack("key", "two")
|
||||
_, _ = red.List().PushBack("key", "thr")
|
||||
|
||||
{
|
||||
cmd := redis.MustParse(ParseLPop, "lpop key")
|
||||
conn := redis.NewFakeConn()
|
||||
res, err := cmd.Run(conn, red)
|
||||
testx.AssertNoErr(t, err)
|
||||
testx.AssertEqual(t, res, core.Value("one"))
|
||||
testx.AssertEqual(t, conn.Out(), "one")
|
||||
be.Err(t, err, nil)
|
||||
be.Equal(t, res.(core.Value), core.Value("one"))
|
||||
be.Equal(t, conn.Out(), "one")
|
||||
}
|
||||
{
|
||||
cmd := redis.MustParse(ParseLPop, "lpop key")
|
||||
conn := redis.NewFakeConn()
|
||||
res, err := cmd.Run(conn, red)
|
||||
testx.AssertNoErr(t, err)
|
||||
testx.AssertEqual(t, res, core.Value("two"))
|
||||
testx.AssertEqual(t, conn.Out(), "two")
|
||||
be.Err(t, err, nil)
|
||||
be.Equal(t, res.(core.Value), core.Value("two"))
|
||||
be.Equal(t, conn.Out(), "two")
|
||||
}
|
||||
})
|
||||
t.Run("key type mismatch", func(t *testing.T) {
|
||||
db, red := getDB(t)
|
||||
defer db.Close()
|
||||
_ = db.Str().Set("key", "str")
|
||||
red := getRedka(t)
|
||||
_ = red.Str().Set("key", "str")
|
||||
|
||||
cmd := redis.MustParse(ParseLPop, "lpop key")
|
||||
conn := redis.NewFakeConn()
|
||||
res, err := cmd.Run(conn, red)
|
||||
testx.AssertNoErr(t, err)
|
||||
testx.AssertEqual(t, res, core.Value(nil))
|
||||
testx.AssertEqual(t, conn.Out(), "(nil)")
|
||||
be.Err(t, err, nil)
|
||||
be.Equal(t, res.(core.Value), core.Value(nil))
|
||||
be.Equal(t, conn.Out(), "(nil)")
|
||||
})
|
||||
}
|
||||
|
||||
@@ -3,9 +3,9 @@ package list
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/nalgeon/be"
|
||||
"github.com/nalgeon/redka/internal/core"
|
||||
"github.com/nalgeon/redka/internal/redis"
|
||||
"github.com/nalgeon/redka/internal/testx"
|
||||
)
|
||||
|
||||
func TestLPushParse(t *testing.T) {
|
||||
@@ -39,10 +39,10 @@ func TestLPushParse(t *testing.T) {
|
||||
for _, test := range tests {
|
||||
t.Run(test.cmd, func(t *testing.T) {
|
||||
cmd, err := redis.Parse(ParseLPush, test.cmd)
|
||||
testx.AssertEqual(t, err, test.err)
|
||||
be.Equal(t, err, test.err)
|
||||
if err == nil {
|
||||
testx.AssertEqual(t, cmd.key, test.want.key)
|
||||
testx.AssertEqual(t, cmd.elem, test.want.elem)
|
||||
be.Equal(t, cmd.key, test.want.key)
|
||||
be.Equal(t, cmd.elem, test.want.elem)
|
||||
}
|
||||
})
|
||||
}
|
||||
@@ -50,70 +50,66 @@ func TestLPushParse(t *testing.T) {
|
||||
|
||||
func TestLPushExec(t *testing.T) {
|
||||
t.Run("empty list", func(t *testing.T) {
|
||||
db, red := getDB(t)
|
||||
defer db.Close()
|
||||
red := getRedka(t)
|
||||
|
||||
cmd := redis.MustParse(ParseLPush, "lpush key elem")
|
||||
conn := redis.NewFakeConn()
|
||||
res, err := cmd.Run(conn, red)
|
||||
testx.AssertNoErr(t, err)
|
||||
testx.AssertEqual(t, res, 1)
|
||||
testx.AssertEqual(t, conn.Out(), "1")
|
||||
be.Err(t, err, nil)
|
||||
be.Equal(t, res, 1)
|
||||
be.Equal(t, conn.Out(), "1")
|
||||
|
||||
elem, _ := db.List().Get("key", 0)
|
||||
testx.AssertEqual(t, elem.String(), "elem")
|
||||
elem, _ := red.List().Get("key", 0)
|
||||
be.Equal(t, elem.String(), "elem")
|
||||
})
|
||||
t.Run("add elem", func(t *testing.T) {
|
||||
db, red := getDB(t)
|
||||
defer db.Close()
|
||||
_, _ = db.List().PushBack("key", "one")
|
||||
red := getRedka(t)
|
||||
_, _ = red.List().PushBack("key", "one")
|
||||
|
||||
cmd := redis.MustParse(ParseLPush, "lpush key two")
|
||||
conn := redis.NewFakeConn()
|
||||
res, err := cmd.Run(conn, red)
|
||||
testx.AssertNoErr(t, err)
|
||||
testx.AssertEqual(t, res, 2)
|
||||
testx.AssertEqual(t, conn.Out(), "2")
|
||||
be.Err(t, err, nil)
|
||||
be.Equal(t, res, 2)
|
||||
be.Equal(t, conn.Out(), "2")
|
||||
|
||||
elem, _ := db.List().Get("key", 0)
|
||||
testx.AssertEqual(t, elem.String(), "two")
|
||||
elem, _ := red.List().Get("key", 0)
|
||||
be.Equal(t, elem.String(), "two")
|
||||
})
|
||||
t.Run("add miltiple", func(t *testing.T) {
|
||||
db, red := getDB(t)
|
||||
defer db.Close()
|
||||
red := getRedka(t)
|
||||
|
||||
{
|
||||
cmd := redis.MustParse(ParseLPush, "lpush key one")
|
||||
conn := redis.NewFakeConn()
|
||||
res, err := cmd.Run(conn, red)
|
||||
testx.AssertNoErr(t, err)
|
||||
testx.AssertEqual(t, res, 1)
|
||||
testx.AssertEqual(t, conn.Out(), "1")
|
||||
be.Err(t, err, nil)
|
||||
be.Equal(t, res, 1)
|
||||
be.Equal(t, conn.Out(), "1")
|
||||
}
|
||||
{
|
||||
cmd := redis.MustParse(ParseLPush, "lpush key two")
|
||||
conn := redis.NewFakeConn()
|
||||
res, err := cmd.Run(conn, red)
|
||||
testx.AssertNoErr(t, err)
|
||||
testx.AssertEqual(t, res, 2)
|
||||
testx.AssertEqual(t, conn.Out(), "2")
|
||||
be.Err(t, err, nil)
|
||||
be.Equal(t, res, 2)
|
||||
be.Equal(t, conn.Out(), "2")
|
||||
}
|
||||
|
||||
el0, _ := db.List().Get("key", 0)
|
||||
testx.AssertEqual(t, el0.String(), "two")
|
||||
el1, _ := db.List().Get("key", 1)
|
||||
testx.AssertEqual(t, el1.String(), "one")
|
||||
el0, _ := red.List().Get("key", 0)
|
||||
be.Equal(t, el0.String(), "two")
|
||||
el1, _ := red.List().Get("key", 1)
|
||||
be.Equal(t, el1.String(), "one")
|
||||
})
|
||||
t.Run("key type mismatch", func(t *testing.T) {
|
||||
db, red := getDB(t)
|
||||
defer db.Close()
|
||||
_ = db.Str().Set("key", "str")
|
||||
red := getRedka(t)
|
||||
_ = red.Str().Set("key", "str")
|
||||
|
||||
cmd := redis.MustParse(ParseLPush, "lpush key elem")
|
||||
conn := redis.NewFakeConn()
|
||||
res, err := cmd.Run(conn, red)
|
||||
testx.AssertErr(t, err, core.ErrKeyType)
|
||||
testx.AssertEqual(t, res, nil)
|
||||
testx.AssertEqual(t, conn.Out(), core.ErrKeyType.Error()+" (lpush)")
|
||||
be.Err(t, err, core.ErrKeyType)
|
||||
be.Equal(t, res, nil)
|
||||
be.Equal(t, conn.Out(), core.ErrKeyType.Error()+" (lpush)")
|
||||
})
|
||||
}
|
||||
|
||||
@@ -3,9 +3,9 @@ package list
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/nalgeon/be"
|
||||
"github.com/nalgeon/redka/internal/core"
|
||||
"github.com/nalgeon/redka/internal/redis"
|
||||
"github.com/nalgeon/redka/internal/testx"
|
||||
)
|
||||
|
||||
func TestLRangeParse(t *testing.T) {
|
||||
@@ -39,13 +39,13 @@ func TestLRangeParse(t *testing.T) {
|
||||
for _, test := range tests {
|
||||
t.Run(test.cmd, func(t *testing.T) {
|
||||
cmd, err := redis.Parse(ParseLRange, test.cmd)
|
||||
testx.AssertEqual(t, err, test.err)
|
||||
be.Equal(t, err, test.err)
|
||||
if err == nil {
|
||||
testx.AssertEqual(t, cmd.key, test.want.key)
|
||||
testx.AssertEqual(t, cmd.start, test.want.start)
|
||||
testx.AssertEqual(t, cmd.stop, test.want.stop)
|
||||
be.Equal(t, cmd.key, test.want.key)
|
||||
be.Equal(t, cmd.start, test.want.start)
|
||||
be.Equal(t, cmd.stop, test.want.stop)
|
||||
} else {
|
||||
testx.AssertEqual(t, cmd, test.want)
|
||||
be.Equal(t, cmd, test.want)
|
||||
}
|
||||
})
|
||||
}
|
||||
@@ -53,94 +53,87 @@ func TestLRangeParse(t *testing.T) {
|
||||
|
||||
func TestLRangeExec(t *testing.T) {
|
||||
t.Run("empty list", func(t *testing.T) {
|
||||
db, red := getDB(t)
|
||||
defer db.Close()
|
||||
red := getRedka(t)
|
||||
|
||||
cmd := redis.MustParse(ParseLRange, "lrange key 0 0")
|
||||
conn := redis.NewFakeConn()
|
||||
res, err := cmd.Run(conn, red)
|
||||
testx.AssertNoErr(t, err)
|
||||
testx.AssertEqual(t, res, []core.Value(nil))
|
||||
testx.AssertEqual(t, conn.Out(), "0")
|
||||
be.Err(t, err, nil)
|
||||
be.Equal(t, res.([]core.Value), []core.Value(nil))
|
||||
be.Equal(t, conn.Out(), "0")
|
||||
})
|
||||
t.Run("single elem", func(t *testing.T) {
|
||||
db, red := getDB(t)
|
||||
defer db.Close()
|
||||
_, _ = db.List().PushBack("key", "elem")
|
||||
red := getRedka(t)
|
||||
_, _ = red.List().PushBack("key", "elem")
|
||||
|
||||
cmd := redis.MustParse(ParseLRange, "lrange key 0 0")
|
||||
conn := redis.NewFakeConn()
|
||||
res, err := cmd.Run(conn, red)
|
||||
testx.AssertNoErr(t, err)
|
||||
testx.AssertEqual(t, res, []core.Value{core.Value("elem")})
|
||||
testx.AssertEqual(t, conn.Out(), "1,elem")
|
||||
be.Err(t, err, nil)
|
||||
be.Equal(t, res.([]core.Value), []core.Value{core.Value("elem")})
|
||||
be.Equal(t, conn.Out(), "1,elem")
|
||||
})
|
||||
t.Run("multiple elems", func(t *testing.T) {
|
||||
db, red := getDB(t)
|
||||
defer db.Close()
|
||||
_, _ = db.List().PushBack("key", "one")
|
||||
_, _ = db.List().PushBack("key", "two")
|
||||
_, _ = db.List().PushBack("key", "thr")
|
||||
red := getRedka(t)
|
||||
_, _ = red.List().PushBack("key", "one")
|
||||
_, _ = red.List().PushBack("key", "two")
|
||||
_, _ = red.List().PushBack("key", "thr")
|
||||
|
||||
cmd := redis.MustParse(ParseLRange, "lrange key 0 1")
|
||||
conn := redis.NewFakeConn()
|
||||
res, err := cmd.Run(conn, red)
|
||||
testx.AssertNoErr(t, err)
|
||||
testx.AssertEqual(t, res, []core.Value{core.Value("one"), core.Value("two")})
|
||||
testx.AssertEqual(t, conn.Out(), "2,one,two")
|
||||
be.Err(t, err, nil)
|
||||
be.Equal(t, res.([]core.Value), []core.Value{core.Value("one"), core.Value("two")})
|
||||
be.Equal(t, conn.Out(), "2,one,two")
|
||||
})
|
||||
t.Run("negative indexes", func(t *testing.T) {
|
||||
db, red := getDB(t)
|
||||
defer db.Close()
|
||||
_, _ = db.List().PushBack("key", "one")
|
||||
_, _ = db.List().PushBack("key", "two")
|
||||
_, _ = db.List().PushBack("key", "thr")
|
||||
red := getRedka(t)
|
||||
_, _ = red.List().PushBack("key", "one")
|
||||
_, _ = red.List().PushBack("key", "two")
|
||||
_, _ = red.List().PushBack("key", "thr")
|
||||
|
||||
cmd := redis.MustParse(ParseLRange, "lrange key -2 -1")
|
||||
conn := redis.NewFakeConn()
|
||||
res, err := cmd.Run(conn, red)
|
||||
testx.AssertNoErr(t, err)
|
||||
testx.AssertEqual(t, res, []core.Value{core.Value("two"), core.Value("thr")})
|
||||
testx.AssertEqual(t, conn.Out(), "2,two,thr")
|
||||
be.Err(t, err, nil)
|
||||
be.Equal(t, res.([]core.Value), []core.Value{core.Value("two"), core.Value("thr")})
|
||||
be.Equal(t, conn.Out(), "2,two,thr")
|
||||
})
|
||||
t.Run("out of bounds", func(t *testing.T) {
|
||||
db, red := getDB(t)
|
||||
defer db.Close()
|
||||
_, _ = db.List().PushBack("key", "one")
|
||||
_, _ = db.List().PushBack("key", "two")
|
||||
_, _ = db.List().PushBack("key", "thr")
|
||||
red := getRedka(t)
|
||||
_, _ = red.List().PushBack("key", "one")
|
||||
_, _ = red.List().PushBack("key", "two")
|
||||
_, _ = red.List().PushBack("key", "thr")
|
||||
|
||||
cmd := redis.MustParse(ParseLRange, "lrange key 3 5")
|
||||
conn := redis.NewFakeConn()
|
||||
res, err := cmd.Run(conn, red)
|
||||
testx.AssertNoErr(t, err)
|
||||
testx.AssertEqual(t, res, []core.Value(nil))
|
||||
testx.AssertEqual(t, conn.Out(), "0")
|
||||
be.Err(t, err, nil)
|
||||
be.Equal(t, res.([]core.Value), []core.Value(nil))
|
||||
be.Equal(t, conn.Out(), "0")
|
||||
})
|
||||
t.Run("start < stop", func(t *testing.T) {
|
||||
db, red := getDB(t)
|
||||
defer db.Close()
|
||||
_, _ = db.List().PushBack("key", "one")
|
||||
_, _ = db.List().PushBack("key", "two")
|
||||
_, _ = db.List().PushBack("key", "thr")
|
||||
red := getRedka(t)
|
||||
_, _ = red.List().PushBack("key", "one")
|
||||
_, _ = red.List().PushBack("key", "two")
|
||||
_, _ = red.List().PushBack("key", "thr")
|
||||
|
||||
cmd := redis.MustParse(ParseLRange, "lrange key 2 1")
|
||||
conn := redis.NewFakeConn()
|
||||
res, err := cmd.Run(conn, red)
|
||||
testx.AssertNoErr(t, err)
|
||||
testx.AssertEqual(t, res, []core.Value(nil))
|
||||
testx.AssertEqual(t, conn.Out(), "0")
|
||||
be.Err(t, err, nil)
|
||||
be.Equal(t, res.([]core.Value), []core.Value(nil))
|
||||
be.Equal(t, conn.Out(), "0")
|
||||
})
|
||||
t.Run("key type mismatch", func(t *testing.T) {
|
||||
db, red := getDB(t)
|
||||
defer db.Close()
|
||||
_ = db.Str().Set("key", "str")
|
||||
red := getRedka(t)
|
||||
_ = red.Str().Set("key", "str")
|
||||
|
||||
cmd := redis.MustParse(ParseLRange, "lrange key 0 0")
|
||||
conn := redis.NewFakeConn()
|
||||
res, err := cmd.Run(conn, red)
|
||||
testx.AssertNoErr(t, err)
|
||||
testx.AssertEqual(t, res, []core.Value(nil))
|
||||
testx.AssertEqual(t, conn.Out(), "0")
|
||||
be.Err(t, err, nil)
|
||||
be.Equal(t, res.([]core.Value), []core.Value(nil))
|
||||
be.Equal(t, conn.Out(), "0")
|
||||
})
|
||||
}
|
||||
|
||||
@@ -3,8 +3,8 @@ package list
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/nalgeon/be"
|
||||
"github.com/nalgeon/redka/internal/redis"
|
||||
"github.com/nalgeon/redka/internal/testx"
|
||||
)
|
||||
|
||||
func TestLRemParse(t *testing.T) {
|
||||
@@ -43,13 +43,13 @@ func TestLRemParse(t *testing.T) {
|
||||
for _, test := range tests {
|
||||
t.Run(test.cmd, func(t *testing.T) {
|
||||
cmd, err := redis.Parse(ParseLRem, test.cmd)
|
||||
testx.AssertEqual(t, err, test.err)
|
||||
be.Equal(t, err, test.err)
|
||||
if err == nil {
|
||||
testx.AssertEqual(t, cmd.key, test.want.key)
|
||||
testx.AssertEqual(t, cmd.count, test.want.count)
|
||||
testx.AssertEqual(t, cmd.elem, test.want.elem)
|
||||
be.Equal(t, cmd.key, test.want.key)
|
||||
be.Equal(t, cmd.count, test.want.count)
|
||||
be.Equal(t, cmd.elem, test.want.elem)
|
||||
} else {
|
||||
testx.AssertEqual(t, cmd, test.want)
|
||||
be.Equal(t, cmd, test.want)
|
||||
}
|
||||
})
|
||||
}
|
||||
@@ -57,120 +57,113 @@ func TestLRemParse(t *testing.T) {
|
||||
|
||||
func TestLRemExec(t *testing.T) {
|
||||
t.Run("empty list", func(t *testing.T) {
|
||||
db, red := getDB(t)
|
||||
defer db.Close()
|
||||
red := getRedka(t)
|
||||
|
||||
cmd := redis.MustParse(ParseLRem, "lrem key 1 elem")
|
||||
conn := redis.NewFakeConn()
|
||||
res, err := cmd.Run(conn, red)
|
||||
testx.AssertNoErr(t, err)
|
||||
testx.AssertEqual(t, res, 0)
|
||||
testx.AssertEqual(t, conn.Out(), "0")
|
||||
be.Err(t, err, nil)
|
||||
be.Equal(t, res, 0)
|
||||
be.Equal(t, conn.Out(), "0")
|
||||
})
|
||||
t.Run("delete elem", func(t *testing.T) {
|
||||
db, red := getDB(t)
|
||||
defer db.Close()
|
||||
_, _ = db.List().PushBack("key", "elem")
|
||||
red := getRedka(t)
|
||||
_, _ = red.List().PushBack("key", "elem")
|
||||
|
||||
cmd := redis.MustParse(ParseLRem, "lrem key 1 elem")
|
||||
conn := redis.NewFakeConn()
|
||||
res, err := cmd.Run(conn, red)
|
||||
testx.AssertNoErr(t, err)
|
||||
testx.AssertEqual(t, res, 1)
|
||||
testx.AssertEqual(t, conn.Out(), "1")
|
||||
be.Err(t, err, nil)
|
||||
be.Equal(t, res, 1)
|
||||
be.Equal(t, conn.Out(), "1")
|
||||
|
||||
count, _ := db.List().Len("key")
|
||||
testx.AssertEqual(t, count, 0)
|
||||
count, _ := red.List().Len("key")
|
||||
be.Equal(t, count, 0)
|
||||
})
|
||||
t.Run("delete front", func(t *testing.T) {
|
||||
db, red := getDB(t)
|
||||
defer db.Close()
|
||||
_, _ = db.List().PushBack("key", "one")
|
||||
_, _ = db.List().PushBack("key", "two")
|
||||
_, _ = db.List().PushBack("key", "two")
|
||||
_, _ = db.List().PushBack("key", "thr")
|
||||
_, _ = db.List().PushBack("key", "two")
|
||||
_, _ = db.List().PushBack("key", "fou")
|
||||
red := getRedka(t)
|
||||
_, _ = red.List().PushBack("key", "one")
|
||||
_, _ = red.List().PushBack("key", "two")
|
||||
_, _ = red.List().PushBack("key", "two")
|
||||
_, _ = red.List().PushBack("key", "thr")
|
||||
_, _ = red.List().PushBack("key", "two")
|
||||
_, _ = red.List().PushBack("key", "fou")
|
||||
|
||||
cmd := redis.MustParse(ParseLRem, "lrem key 2 two")
|
||||
conn := redis.NewFakeConn()
|
||||
res, err := cmd.Run(conn, red)
|
||||
testx.AssertNoErr(t, err)
|
||||
testx.AssertEqual(t, res, 2)
|
||||
testx.AssertEqual(t, conn.Out(), "2")
|
||||
be.Err(t, err, nil)
|
||||
be.Equal(t, res, 2)
|
||||
be.Equal(t, conn.Out(), "2")
|
||||
|
||||
count, _ := db.List().Len("key")
|
||||
testx.AssertEqual(t, count, 4)
|
||||
el1, _ := db.List().Get("key", 1)
|
||||
testx.AssertEqual(t, el1.String(), "thr")
|
||||
count, _ := red.List().Len("key")
|
||||
be.Equal(t, count, 4)
|
||||
el1, _ := red.List().Get("key", 1)
|
||||
be.Equal(t, el1.String(), "thr")
|
||||
})
|
||||
t.Run("delete back", func(t *testing.T) {
|
||||
db, red := getDB(t)
|
||||
defer db.Close()
|
||||
_, _ = db.List().PushBack("key", "one")
|
||||
_, _ = db.List().PushBack("key", "two")
|
||||
_, _ = db.List().PushBack("key", "two")
|
||||
_, _ = db.List().PushBack("key", "thr")
|
||||
_, _ = db.List().PushBack("key", "two")
|
||||
_, _ = db.List().PushBack("key", "fou")
|
||||
red := getRedka(t)
|
||||
_, _ = red.List().PushBack("key", "one")
|
||||
_, _ = red.List().PushBack("key", "two")
|
||||
_, _ = red.List().PushBack("key", "two")
|
||||
_, _ = red.List().PushBack("key", "thr")
|
||||
_, _ = red.List().PushBack("key", "two")
|
||||
_, _ = red.List().PushBack("key", "fou")
|
||||
|
||||
cmd := redis.MustParse(ParseLRem, "lrem key -2 two")
|
||||
conn := redis.NewFakeConn()
|
||||
res, err := cmd.Run(conn, red)
|
||||
testx.AssertNoErr(t, err)
|
||||
testx.AssertEqual(t, res, 2)
|
||||
testx.AssertEqual(t, conn.Out(), "2")
|
||||
be.Err(t, err, nil)
|
||||
be.Equal(t, res, 2)
|
||||
be.Equal(t, conn.Out(), "2")
|
||||
|
||||
count, _ := db.List().Len("key")
|
||||
testx.AssertEqual(t, count, 4)
|
||||
el1, _ := db.List().Get("key", 1)
|
||||
testx.AssertEqual(t, el1.String(), "two")
|
||||
count, _ := red.List().Len("key")
|
||||
be.Equal(t, count, 4)
|
||||
el1, _ := red.List().Get("key", 1)
|
||||
be.Equal(t, el1.String(), "two")
|
||||
})
|
||||
t.Run("delete all", func(t *testing.T) {
|
||||
db, red := getDB(t)
|
||||
defer db.Close()
|
||||
_, _ = db.List().PushBack("key", "one")
|
||||
_, _ = db.List().PushBack("key", "two")
|
||||
_, _ = db.List().PushBack("key", "two")
|
||||
_, _ = db.List().PushBack("key", "thr")
|
||||
_, _ = db.List().PushBack("key", "two")
|
||||
_, _ = db.List().PushBack("key", "fou")
|
||||
red := getRedka(t)
|
||||
_, _ = red.List().PushBack("key", "one")
|
||||
_, _ = red.List().PushBack("key", "two")
|
||||
_, _ = red.List().PushBack("key", "two")
|
||||
_, _ = red.List().PushBack("key", "thr")
|
||||
_, _ = red.List().PushBack("key", "two")
|
||||
_, _ = red.List().PushBack("key", "fou")
|
||||
|
||||
cmd := redis.MustParse(ParseLRem, "lrem key 0 two")
|
||||
conn := redis.NewFakeConn()
|
||||
res, err := cmd.Run(conn, red)
|
||||
testx.AssertNoErr(t, err)
|
||||
testx.AssertEqual(t, res, 3)
|
||||
testx.AssertEqual(t, conn.Out(), "3")
|
||||
be.Err(t, err, nil)
|
||||
be.Equal(t, res, 3)
|
||||
be.Equal(t, conn.Out(), "3")
|
||||
|
||||
count, _ := db.List().Len("key")
|
||||
testx.AssertEqual(t, count, 3)
|
||||
count, _ := red.List().Len("key")
|
||||
be.Equal(t, count, 3)
|
||||
})
|
||||
t.Run("elem not found", func(t *testing.T) {
|
||||
db, red := getDB(t)
|
||||
defer db.Close()
|
||||
_, _ = db.List().PushBack("key", "elem")
|
||||
red := getRedka(t)
|
||||
_, _ = red.List().PushBack("key", "elem")
|
||||
|
||||
cmd := redis.MustParse(ParseLRem, "lrem key 1 other")
|
||||
conn := redis.NewFakeConn()
|
||||
res, err := cmd.Run(conn, red)
|
||||
testx.AssertNoErr(t, err)
|
||||
testx.AssertEqual(t, res, 0)
|
||||
testx.AssertEqual(t, conn.Out(), "0")
|
||||
be.Err(t, err, nil)
|
||||
be.Equal(t, res, 0)
|
||||
be.Equal(t, conn.Out(), "0")
|
||||
|
||||
count, _ := db.List().Len("key")
|
||||
testx.AssertEqual(t, count, 1)
|
||||
count, _ := red.List().Len("key")
|
||||
be.Equal(t, count, 1)
|
||||
})
|
||||
t.Run("key type mismatch", func(t *testing.T) {
|
||||
db, red := getDB(t)
|
||||
defer db.Close()
|
||||
_ = db.Str().Set("key", "str")
|
||||
red := getRedka(t)
|
||||
_ = red.Str().Set("key", "str")
|
||||
|
||||
cmd := redis.MustParse(ParseLRem, "lrem key 1 elem")
|
||||
conn := redis.NewFakeConn()
|
||||
res, err := cmd.Run(conn, red)
|
||||
testx.AssertNoErr(t, err)
|
||||
testx.AssertEqual(t, res, 0)
|
||||
testx.AssertEqual(t, conn.Out(), "0")
|
||||
be.Err(t, err, nil)
|
||||
be.Equal(t, res, 0)
|
||||
be.Equal(t, conn.Out(), "0")
|
||||
})
|
||||
}
|
||||
|
||||
@@ -3,9 +3,9 @@ package list
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/nalgeon/be"
|
||||
"github.com/nalgeon/redka/internal/core"
|
||||
"github.com/nalgeon/redka/internal/redis"
|
||||
"github.com/nalgeon/redka/internal/testx"
|
||||
)
|
||||
|
||||
func TestLSetParse(t *testing.T) {
|
||||
@@ -44,13 +44,13 @@ func TestLSetParse(t *testing.T) {
|
||||
for _, test := range tests {
|
||||
t.Run(test.cmd, func(t *testing.T) {
|
||||
cmd, err := redis.Parse(ParseLSet, test.cmd)
|
||||
testx.AssertEqual(t, err, test.err)
|
||||
be.Equal(t, err, test.err)
|
||||
if err == nil {
|
||||
testx.AssertEqual(t, cmd.key, test.want.key)
|
||||
testx.AssertEqual(t, cmd.index, test.want.index)
|
||||
testx.AssertEqual(t, cmd.elem, test.want.elem)
|
||||
be.Equal(t, cmd.key, test.want.key)
|
||||
be.Equal(t, cmd.index, test.want.index)
|
||||
be.Equal(t, cmd.elem, test.want.elem)
|
||||
} else {
|
||||
testx.AssertEqual(t, cmd, test.want)
|
||||
be.Equal(t, cmd, test.want)
|
||||
}
|
||||
})
|
||||
}
|
||||
@@ -58,72 +58,67 @@ func TestLSetParse(t *testing.T) {
|
||||
|
||||
func TestLSetExec(t *testing.T) {
|
||||
t.Run("empty list", func(t *testing.T) {
|
||||
db, red := getDB(t)
|
||||
defer db.Close()
|
||||
red := getRedka(t)
|
||||
|
||||
cmd := redis.MustParse(ParseLSet, "lset key 0 elem")
|
||||
conn := redis.NewFakeConn()
|
||||
res, err := cmd.Run(conn, red)
|
||||
testx.AssertErr(t, err, core.ErrNotFound)
|
||||
testx.AssertEqual(t, res, nil)
|
||||
testx.AssertEqual(t, conn.Out(), redis.ErrOutOfRange.Error()+" (lset)")
|
||||
be.Err(t, err, core.ErrNotFound)
|
||||
be.Equal(t, res, nil)
|
||||
be.Equal(t, conn.Out(), redis.ErrOutOfRange.Error()+" (lset)")
|
||||
})
|
||||
t.Run("set elem", func(t *testing.T) {
|
||||
db, red := getDB(t)
|
||||
defer db.Close()
|
||||
_, _ = db.List().PushBack("key", "one")
|
||||
_, _ = db.List().PushBack("key", "two")
|
||||
_, _ = db.List().PushBack("key", "thr")
|
||||
red := getRedka(t)
|
||||
_, _ = red.List().PushBack("key", "one")
|
||||
_, _ = red.List().PushBack("key", "two")
|
||||
_, _ = red.List().PushBack("key", "thr")
|
||||
|
||||
cmd := redis.MustParse(ParseLSet, "lset key 1 upd")
|
||||
conn := redis.NewFakeConn()
|
||||
res, err := cmd.Run(conn, red)
|
||||
testx.AssertNoErr(t, err)
|
||||
testx.AssertEqual(t, res, nil)
|
||||
testx.AssertEqual(t, conn.Out(), "OK")
|
||||
be.Err(t, err, nil)
|
||||
be.Equal(t, res, nil)
|
||||
be.Equal(t, conn.Out(), "OK")
|
||||
|
||||
el1, _ := db.List().Get("key", 1)
|
||||
testx.AssertEqual(t, el1.String(), "upd")
|
||||
el1, _ := red.List().Get("key", 1)
|
||||
be.Equal(t, el1.String(), "upd")
|
||||
})
|
||||
t.Run("negative index", func(t *testing.T) {
|
||||
db, red := getDB(t)
|
||||
defer db.Close()
|
||||
_, _ = db.List().PushBack("key", "one")
|
||||
_, _ = db.List().PushBack("key", "two")
|
||||
_, _ = db.List().PushBack("key", "thr")
|
||||
red := getRedka(t)
|
||||
_, _ = red.List().PushBack("key", "one")
|
||||
_, _ = red.List().PushBack("key", "two")
|
||||
_, _ = red.List().PushBack("key", "thr")
|
||||
|
||||
cmd := redis.MustParse(ParseLSet, "lset key -1 upd")
|
||||
conn := redis.NewFakeConn()
|
||||
res, err := cmd.Run(conn, red)
|
||||
testx.AssertNoErr(t, err)
|
||||
testx.AssertEqual(t, res, nil)
|
||||
testx.AssertEqual(t, conn.Out(), "OK")
|
||||
be.Err(t, err, nil)
|
||||
be.Equal(t, res, nil)
|
||||
be.Equal(t, conn.Out(), "OK")
|
||||
|
||||
el2, _ := db.List().Get("key", 2)
|
||||
testx.AssertEqual(t, el2.String(), "upd")
|
||||
el2, _ := red.List().Get("key", 2)
|
||||
be.Equal(t, el2.String(), "upd")
|
||||
})
|
||||
t.Run("index out of bounds", func(t *testing.T) {
|
||||
db, red := getDB(t)
|
||||
defer db.Close()
|
||||
_, _ = db.List().PushBack("key", "elem")
|
||||
red := getRedka(t)
|
||||
_, _ = red.List().PushBack("key", "elem")
|
||||
|
||||
cmd := redis.MustParse(ParseLSet, "lset key 1 upd")
|
||||
conn := redis.NewFakeConn()
|
||||
res, err := cmd.Run(conn, red)
|
||||
testx.AssertErr(t, err, core.ErrNotFound)
|
||||
testx.AssertEqual(t, res, nil)
|
||||
testx.AssertEqual(t, conn.Out(), redis.ErrOutOfRange.Error()+" (lset)")
|
||||
be.Err(t, err, core.ErrNotFound)
|
||||
be.Equal(t, res, nil)
|
||||
be.Equal(t, conn.Out(), redis.ErrOutOfRange.Error()+" (lset)")
|
||||
})
|
||||
t.Run("key type mismatch", func(t *testing.T) {
|
||||
db, red := getDB(t)
|
||||
defer db.Close()
|
||||
_ = db.Str().Set("key", "str")
|
||||
red := getRedka(t)
|
||||
_ = red.Str().Set("key", "str")
|
||||
|
||||
cmd := redis.MustParse(ParseLSet, "lset key 0 elem")
|
||||
conn := redis.NewFakeConn()
|
||||
res, err := cmd.Run(conn, red)
|
||||
testx.AssertErr(t, err, core.ErrNotFound)
|
||||
testx.AssertEqual(t, res, nil)
|
||||
testx.AssertEqual(t, conn.Out(), redis.ErrOutOfRange.Error()+" (lset)")
|
||||
be.Err(t, err, core.ErrNotFound)
|
||||
be.Equal(t, res, nil)
|
||||
be.Equal(t, conn.Out(), redis.ErrOutOfRange.Error()+" (lset)")
|
||||
})
|
||||
}
|
||||
|
||||
@@ -3,8 +3,8 @@ package list
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/nalgeon/be"
|
||||
"github.com/nalgeon/redka/internal/redis"
|
||||
"github.com/nalgeon/redka/internal/testx"
|
||||
)
|
||||
|
||||
func TestLTrimParse(t *testing.T) {
|
||||
@@ -33,13 +33,13 @@ func TestLTrimParse(t *testing.T) {
|
||||
for _, test := range tests {
|
||||
t.Run(test.cmd, func(t *testing.T) {
|
||||
cmd, err := redis.Parse(ParseLTrim, test.cmd)
|
||||
testx.AssertEqual(t, err, test.err)
|
||||
be.Equal(t, err, test.err)
|
||||
if err == nil {
|
||||
testx.AssertEqual(t, cmd.key, test.want.key)
|
||||
testx.AssertEqual(t, cmd.start, test.want.start)
|
||||
testx.AssertEqual(t, cmd.stop, test.want.stop)
|
||||
be.Equal(t, cmd.key, test.want.key)
|
||||
be.Equal(t, cmd.start, test.want.start)
|
||||
be.Equal(t, cmd.stop, test.want.stop)
|
||||
} else {
|
||||
testx.AssertEqual(t, cmd, test.want)
|
||||
be.Equal(t, cmd, test.want)
|
||||
}
|
||||
})
|
||||
}
|
||||
@@ -47,98 +47,92 @@ func TestLTrimParse(t *testing.T) {
|
||||
|
||||
func TestLTrimExec(t *testing.T) {
|
||||
t.Run("empty list", func(t *testing.T) {
|
||||
db, red := getDB(t)
|
||||
defer db.Close()
|
||||
red := getRedka(t)
|
||||
|
||||
cmd := redis.MustParse(ParseLTrim, "ltrim key 0 0")
|
||||
conn := redis.NewFakeConn()
|
||||
res, err := cmd.Run(conn, red)
|
||||
testx.AssertNoErr(t, err)
|
||||
testx.AssertEqual(t, res, 0)
|
||||
testx.AssertEqual(t, conn.Out(), "OK")
|
||||
be.Err(t, err, nil)
|
||||
be.Equal(t, res, 0)
|
||||
be.Equal(t, conn.Out(), "OK")
|
||||
})
|
||||
t.Run("keep single elem", func(t *testing.T) {
|
||||
db, red := getDB(t)
|
||||
defer db.Close()
|
||||
_, _ = db.List().PushBack("key", "elem")
|
||||
red := getRedka(t)
|
||||
_, _ = red.List().PushBack("key", "elem")
|
||||
|
||||
cmd := redis.MustParse(ParseLTrim, "ltrim key 0 0")
|
||||
conn := redis.NewFakeConn()
|
||||
res, err := cmd.Run(conn, red)
|
||||
testx.AssertNoErr(t, err)
|
||||
testx.AssertEqual(t, res, 0)
|
||||
testx.AssertEqual(t, conn.Out(), "OK")
|
||||
be.Err(t, err, nil)
|
||||
be.Equal(t, res, 0)
|
||||
be.Equal(t, conn.Out(), "OK")
|
||||
|
||||
count, _ := db.List().Len("key")
|
||||
testx.AssertEqual(t, count, 1)
|
||||
count, _ := red.List().Len("key")
|
||||
be.Equal(t, count, 1)
|
||||
})
|
||||
t.Run("keep multiple elems", func(t *testing.T) {
|
||||
db, red := getDB(t)
|
||||
defer db.Close()
|
||||
_, _ = db.List().PushBack("key", "one")
|
||||
_, _ = db.List().PushBack("key", "two")
|
||||
_, _ = db.List().PushBack("key", "thr")
|
||||
_, _ = db.List().PushBack("key", "fou")
|
||||
red := getRedka(t)
|
||||
_, _ = red.List().PushBack("key", "one")
|
||||
_, _ = red.List().PushBack("key", "two")
|
||||
_, _ = red.List().PushBack("key", "thr")
|
||||
_, _ = red.List().PushBack("key", "fou")
|
||||
|
||||
cmd := redis.MustParse(ParseLTrim, "ltrim key 1 2")
|
||||
conn := redis.NewFakeConn()
|
||||
res, err := cmd.Run(conn, red)
|
||||
testx.AssertNoErr(t, err)
|
||||
testx.AssertEqual(t, res, 2)
|
||||
testx.AssertEqual(t, conn.Out(), "OK")
|
||||
be.Err(t, err, nil)
|
||||
be.Equal(t, res, 2)
|
||||
be.Equal(t, conn.Out(), "OK")
|
||||
|
||||
count, _ := db.List().Len("key")
|
||||
testx.AssertEqual(t, count, 2)
|
||||
el0, _ := db.List().Get("key", 0)
|
||||
testx.AssertEqual(t, el0.String(), "two")
|
||||
el1, _ := db.List().Get("key", 1)
|
||||
testx.AssertEqual(t, el1.String(), "thr")
|
||||
count, _ := red.List().Len("key")
|
||||
be.Equal(t, count, 2)
|
||||
el0, _ := red.List().Get("key", 0)
|
||||
be.Equal(t, el0.String(), "two")
|
||||
el1, _ := red.List().Get("key", 1)
|
||||
be.Equal(t, el1.String(), "thr")
|
||||
})
|
||||
t.Run("negative index", func(t *testing.T) {
|
||||
db, red := getDB(t)
|
||||
defer db.Close()
|
||||
_, _ = db.List().PushBack("key", "one")
|
||||
_, _ = db.List().PushBack("key", "two")
|
||||
_, _ = db.List().PushBack("key", "thr")
|
||||
_, _ = db.List().PushBack("key", "fou")
|
||||
red := getRedka(t)
|
||||
_, _ = red.List().PushBack("key", "one")
|
||||
_, _ = red.List().PushBack("key", "two")
|
||||
_, _ = red.List().PushBack("key", "thr")
|
||||
_, _ = red.List().PushBack("key", "fou")
|
||||
|
||||
cmd := redis.MustParse(ParseLTrim, "ltrim key 0 -1")
|
||||
conn := redis.NewFakeConn()
|
||||
res, err := cmd.Run(conn, red)
|
||||
testx.AssertNoErr(t, err)
|
||||
testx.AssertEqual(t, res, 0)
|
||||
testx.AssertEqual(t, conn.Out(), "OK")
|
||||
be.Err(t, err, nil)
|
||||
be.Equal(t, res, 0)
|
||||
be.Equal(t, conn.Out(), "OK")
|
||||
|
||||
count, _ := db.List().Len("key")
|
||||
testx.AssertEqual(t, count, 4)
|
||||
count, _ := red.List().Len("key")
|
||||
be.Equal(t, count, 4)
|
||||
})
|
||||
t.Run("start > stop", func(t *testing.T) {
|
||||
db, red := getDB(t)
|
||||
defer db.Close()
|
||||
_, _ = db.List().PushBack("key", "one")
|
||||
_, _ = db.List().PushBack("key", "two")
|
||||
_, _ = db.List().PushBack("key", "thr")
|
||||
red := getRedka(t)
|
||||
_, _ = red.List().PushBack("key", "one")
|
||||
_, _ = red.List().PushBack("key", "two")
|
||||
_, _ = red.List().PushBack("key", "thr")
|
||||
|
||||
cmd := redis.MustParse(ParseLTrim, "ltrim key 2 1")
|
||||
conn := redis.NewFakeConn()
|
||||
res, err := cmd.Run(conn, red)
|
||||
testx.AssertNoErr(t, err)
|
||||
testx.AssertEqual(t, res, 3)
|
||||
testx.AssertEqual(t, conn.Out(), "OK")
|
||||
be.Err(t, err, nil)
|
||||
be.Equal(t, res, 3)
|
||||
be.Equal(t, conn.Out(), "OK")
|
||||
|
||||
count, _ := db.List().Len("key")
|
||||
testx.AssertEqual(t, count, 0)
|
||||
count, _ := red.List().Len("key")
|
||||
be.Equal(t, count, 0)
|
||||
})
|
||||
t.Run("key type mismatch", func(t *testing.T) {
|
||||
db, red := getDB(t)
|
||||
defer db.Close()
|
||||
_ = db.Str().Set("key", "str")
|
||||
red := getRedka(t)
|
||||
_ = red.Str().Set("key", "str")
|
||||
|
||||
cmd := redis.MustParse(ParseLTrim, "ltrim key 0 0")
|
||||
conn := redis.NewFakeConn()
|
||||
res, err := cmd.Run(conn, red)
|
||||
testx.AssertNoErr(t, err)
|
||||
testx.AssertEqual(t, res, 0)
|
||||
testx.AssertEqual(t, conn.Out(), "OK")
|
||||
be.Err(t, err, nil)
|
||||
be.Equal(t, res, 0)
|
||||
be.Equal(t, conn.Out(), "OK")
|
||||
})
|
||||
}
|
||||
|
||||
@@ -3,9 +3,9 @@ package list
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/nalgeon/be"
|
||||
"github.com/nalgeon/redka/internal/core"
|
||||
"github.com/nalgeon/redka/internal/redis"
|
||||
"github.com/nalgeon/redka/internal/testx"
|
||||
)
|
||||
|
||||
func TestRPopParse(t *testing.T) {
|
||||
@@ -34,11 +34,11 @@ func TestRPopParse(t *testing.T) {
|
||||
for _, test := range tests {
|
||||
t.Run(test.cmd, func(t *testing.T) {
|
||||
cmd, err := redis.Parse(ParseRPop, test.cmd)
|
||||
testx.AssertEqual(t, err, test.err)
|
||||
be.Equal(t, err, test.err)
|
||||
if err == nil {
|
||||
testx.AssertEqual(t, cmd.key, test.want.key)
|
||||
be.Equal(t, cmd.key, test.want.key)
|
||||
} else {
|
||||
testx.AssertEqual(t, cmd, test.want)
|
||||
be.Equal(t, cmd, test.want)
|
||||
}
|
||||
})
|
||||
}
|
||||
@@ -46,62 +46,58 @@ func TestRPopParse(t *testing.T) {
|
||||
|
||||
func TestRPopExec(t *testing.T) {
|
||||
t.Run("empty list", func(t *testing.T) {
|
||||
db, red := getDB(t)
|
||||
defer db.Close()
|
||||
red := getRedka(t)
|
||||
|
||||
cmd := redis.MustParse(ParseRPop, "rpop key")
|
||||
conn := redis.NewFakeConn()
|
||||
res, err := cmd.Run(conn, red)
|
||||
testx.AssertNoErr(t, err)
|
||||
testx.AssertEqual(t, res, core.Value(nil))
|
||||
testx.AssertEqual(t, conn.Out(), "(nil)")
|
||||
be.Err(t, err, nil)
|
||||
be.Equal(t, res.(core.Value), core.Value(nil))
|
||||
be.Equal(t, conn.Out(), "(nil)")
|
||||
})
|
||||
t.Run("pop elem", func(t *testing.T) {
|
||||
db, red := getDB(t)
|
||||
defer db.Close()
|
||||
_, _ = db.List().PushBack("key", "elem")
|
||||
red := getRedka(t)
|
||||
_, _ = red.List().PushBack("key", "elem")
|
||||
|
||||
cmd := redis.MustParse(ParseRPop, "rpop key")
|
||||
conn := redis.NewFakeConn()
|
||||
res, err := cmd.Run(conn, red)
|
||||
testx.AssertNoErr(t, err)
|
||||
testx.AssertEqual(t, res, core.Value("elem"))
|
||||
testx.AssertEqual(t, conn.Out(), "elem")
|
||||
be.Err(t, err, nil)
|
||||
be.Equal(t, res.(core.Value), core.Value("elem"))
|
||||
be.Equal(t, conn.Out(), "elem")
|
||||
})
|
||||
t.Run("pop multiple", func(t *testing.T) {
|
||||
db, red := getDB(t)
|
||||
defer db.Close()
|
||||
_, _ = db.List().PushBack("key", "one")
|
||||
_, _ = db.List().PushBack("key", "two")
|
||||
_, _ = db.List().PushBack("key", "thr")
|
||||
red := getRedka(t)
|
||||
_, _ = red.List().PushBack("key", "one")
|
||||
_, _ = red.List().PushBack("key", "two")
|
||||
_, _ = red.List().PushBack("key", "thr")
|
||||
|
||||
{
|
||||
cmd := redis.MustParse(ParseRPop, "rpop key")
|
||||
conn := redis.NewFakeConn()
|
||||
res, err := cmd.Run(conn, red)
|
||||
testx.AssertNoErr(t, err)
|
||||
testx.AssertEqual(t, res, core.Value("thr"))
|
||||
testx.AssertEqual(t, conn.Out(), "thr")
|
||||
be.Err(t, err, nil)
|
||||
be.Equal(t, res.(core.Value), core.Value("thr"))
|
||||
be.Equal(t, conn.Out(), "thr")
|
||||
}
|
||||
{
|
||||
cmd := redis.MustParse(ParseRPop, "rpop key")
|
||||
conn := redis.NewFakeConn()
|
||||
res, err := cmd.Run(conn, red)
|
||||
testx.AssertNoErr(t, err)
|
||||
testx.AssertEqual(t, res, core.Value("two"))
|
||||
testx.AssertEqual(t, conn.Out(), "two")
|
||||
be.Err(t, err, nil)
|
||||
be.Equal(t, res.(core.Value), core.Value("two"))
|
||||
be.Equal(t, conn.Out(), "two")
|
||||
}
|
||||
})
|
||||
t.Run("key type mismatch", func(t *testing.T) {
|
||||
db, red := getDB(t)
|
||||
defer db.Close()
|
||||
_ = db.Str().Set("key", "str")
|
||||
red := getRedka(t)
|
||||
_ = red.Str().Set("key", "str")
|
||||
|
||||
cmd := redis.MustParse(ParseRPop, "rpop key")
|
||||
conn := redis.NewFakeConn()
|
||||
res, err := cmd.Run(conn, red)
|
||||
testx.AssertNoErr(t, err)
|
||||
testx.AssertEqual(t, res, core.Value(nil))
|
||||
testx.AssertEqual(t, conn.Out(), "(nil)")
|
||||
be.Err(t, err, nil)
|
||||
be.Equal(t, res.(core.Value), core.Value(nil))
|
||||
be.Equal(t, conn.Out(), "(nil)")
|
||||
})
|
||||
}
|
||||
|
||||
@@ -3,9 +3,9 @@ package list
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/nalgeon/be"
|
||||
"github.com/nalgeon/redka/internal/core"
|
||||
"github.com/nalgeon/redka/internal/redis"
|
||||
"github.com/nalgeon/redka/internal/testx"
|
||||
)
|
||||
|
||||
func TestRPopLPushParse(t *testing.T) {
|
||||
@@ -34,12 +34,12 @@ func TestRPopLPushParse(t *testing.T) {
|
||||
for _, test := range tests {
|
||||
t.Run(test.cmd, func(t *testing.T) {
|
||||
cmd, err := redis.Parse(ParseRPopLPush, test.cmd)
|
||||
testx.AssertEqual(t, err, test.err)
|
||||
be.Equal(t, err, test.err)
|
||||
if err == nil {
|
||||
testx.AssertEqual(t, cmd.src, test.want.src)
|
||||
testx.AssertEqual(t, cmd.dst, test.want.dst)
|
||||
be.Equal(t, cmd.src, test.want.src)
|
||||
be.Equal(t, cmd.dst, test.want.dst)
|
||||
} else {
|
||||
testx.AssertEqual(t, cmd, test.want)
|
||||
be.Equal(t, cmd, test.want)
|
||||
}
|
||||
})
|
||||
}
|
||||
@@ -47,101 +47,96 @@ func TestRPopLPushParse(t *testing.T) {
|
||||
|
||||
func TestRPopLPushExec(t *testing.T) {
|
||||
t.Run("src not found", func(t *testing.T) {
|
||||
db, red := getDB(t)
|
||||
defer db.Close()
|
||||
red := getRedka(t)
|
||||
|
||||
cmd := redis.MustParse(ParseRPopLPush, "rpoplpush src dst")
|
||||
conn := redis.NewFakeConn()
|
||||
res, err := cmd.Run(conn, red)
|
||||
testx.AssertNoErr(t, err)
|
||||
testx.AssertEqual(t, res, core.Value(nil))
|
||||
testx.AssertEqual(t, conn.Out(), "(nil)")
|
||||
be.Err(t, err, nil)
|
||||
be.Equal(t, res.(core.Value), core.Value(nil))
|
||||
be.Equal(t, conn.Out(), "(nil)")
|
||||
})
|
||||
t.Run("pop elem", func(t *testing.T) {
|
||||
db, red := getDB(t)
|
||||
defer db.Close()
|
||||
_, _ = db.List().PushBack("src", "elem")
|
||||
red := getRedka(t)
|
||||
_, _ = red.List().PushBack("src", "elem")
|
||||
|
||||
cmd := redis.MustParse(ParseRPopLPush, "rpoplpush src dst")
|
||||
conn := redis.NewFakeConn()
|
||||
res, err := cmd.Run(conn, red)
|
||||
testx.AssertNoErr(t, err)
|
||||
testx.AssertEqual(t, res, core.Value("elem"))
|
||||
testx.AssertEqual(t, conn.Out(), "elem")
|
||||
be.Err(t, err, nil)
|
||||
be.Equal(t, res.(core.Value), core.Value("elem"))
|
||||
be.Equal(t, conn.Out(), "elem")
|
||||
|
||||
count, _ := db.List().Len("src")
|
||||
testx.AssertEqual(t, count, 0)
|
||||
count, _ = db.List().Len("dst")
|
||||
testx.AssertEqual(t, count, 1)
|
||||
count, _ := red.List().Len("src")
|
||||
be.Equal(t, count, 0)
|
||||
count, _ = red.List().Len("dst")
|
||||
be.Equal(t, count, 1)
|
||||
})
|
||||
t.Run("pop multiple", func(t *testing.T) {
|
||||
db, red := getDB(t)
|
||||
defer db.Close()
|
||||
_, _ = db.List().PushBack("src", "one")
|
||||
_, _ = db.List().PushBack("src", "two")
|
||||
_, _ = db.List().PushBack("src", "thr")
|
||||
red := getRedka(t)
|
||||
_, _ = red.List().PushBack("src", "one")
|
||||
_, _ = red.List().PushBack("src", "two")
|
||||
_, _ = red.List().PushBack("src", "thr")
|
||||
|
||||
{
|
||||
cmd := redis.MustParse(ParseRPopLPush, "rpoplpush src dst")
|
||||
conn := redis.NewFakeConn()
|
||||
res, err := cmd.Run(conn, red)
|
||||
testx.AssertNoErr(t, err)
|
||||
testx.AssertEqual(t, res, core.Value("thr"))
|
||||
testx.AssertEqual(t, conn.Out(), "thr")
|
||||
be.Err(t, err, nil)
|
||||
be.Equal(t, res.(core.Value), core.Value("thr"))
|
||||
be.Equal(t, conn.Out(), "thr")
|
||||
}
|
||||
{
|
||||
cmd := redis.MustParse(ParseRPopLPush, "rpoplpush src dst")
|
||||
conn := redis.NewFakeConn()
|
||||
res, err := cmd.Run(conn, red)
|
||||
testx.AssertNoErr(t, err)
|
||||
testx.AssertEqual(t, res, core.Value("two"))
|
||||
testx.AssertEqual(t, conn.Out(), "two")
|
||||
be.Err(t, err, nil)
|
||||
be.Equal(t, res.(core.Value), core.Value("two"))
|
||||
be.Equal(t, conn.Out(), "two")
|
||||
}
|
||||
|
||||
count, _ := db.List().Len("src")
|
||||
testx.AssertEqual(t, count, 1)
|
||||
count, _ = db.List().Len("dst")
|
||||
testx.AssertEqual(t, count, 2)
|
||||
count, _ := red.List().Len("src")
|
||||
be.Equal(t, count, 1)
|
||||
count, _ = red.List().Len("dst")
|
||||
be.Equal(t, count, 2)
|
||||
})
|
||||
t.Run("push to self", func(t *testing.T) {
|
||||
db, red := getDB(t)
|
||||
defer db.Close()
|
||||
_, _ = db.List().PushBack("src", "one")
|
||||
_, _ = db.List().PushBack("src", "two")
|
||||
_, _ = db.List().PushBack("src", "thr")
|
||||
red := getRedka(t)
|
||||
_, _ = red.List().PushBack("src", "one")
|
||||
_, _ = red.List().PushBack("src", "two")
|
||||
_, _ = red.List().PushBack("src", "thr")
|
||||
|
||||
{
|
||||
cmd := redis.MustParse(ParseRPopLPush, "rpoplpush src src")
|
||||
conn := redis.NewFakeConn()
|
||||
res, err := cmd.Run(conn, red)
|
||||
testx.AssertNoErr(t, err)
|
||||
testx.AssertEqual(t, res, core.Value("thr"))
|
||||
testx.AssertEqual(t, conn.Out(), "thr")
|
||||
be.Err(t, err, nil)
|
||||
be.Equal(t, res.(core.Value), core.Value("thr"))
|
||||
be.Equal(t, conn.Out(), "thr")
|
||||
}
|
||||
{
|
||||
cmd := redis.MustParse(ParseRPopLPush, "rpoplpush src src")
|
||||
conn := redis.NewFakeConn()
|
||||
res, err := cmd.Run(conn, red)
|
||||
testx.AssertNoErr(t, err)
|
||||
testx.AssertEqual(t, res, core.Value("two"))
|
||||
testx.AssertEqual(t, conn.Out(), "two")
|
||||
be.Err(t, err, nil)
|
||||
be.Equal(t, res.(core.Value), core.Value("two"))
|
||||
be.Equal(t, conn.Out(), "two")
|
||||
}
|
||||
|
||||
elems, _ := db.List().Range("src", 0, -1)
|
||||
testx.AssertEqual(t, elems[0].String(), "two")
|
||||
testx.AssertEqual(t, elems[1].String(), "thr")
|
||||
testx.AssertEqual(t, elems[2].String(), "one")
|
||||
elems, _ := red.List().Range("src", 0, -1)
|
||||
be.Equal(t, elems[0].String(), "two")
|
||||
be.Equal(t, elems[1].String(), "thr")
|
||||
be.Equal(t, elems[2].String(), "one")
|
||||
})
|
||||
t.Run("key type mismatch", func(t *testing.T) {
|
||||
db, red := getDB(t)
|
||||
defer db.Close()
|
||||
_ = db.Str().Set("src", "str")
|
||||
red := getRedka(t)
|
||||
_ = red.Str().Set("src", "str")
|
||||
|
||||
cmd := redis.MustParse(ParseRPopLPush, "rpoplpush src dst")
|
||||
conn := redis.NewFakeConn()
|
||||
res, err := cmd.Run(conn, red)
|
||||
testx.AssertNoErr(t, err)
|
||||
testx.AssertEqual(t, res, core.Value(nil))
|
||||
testx.AssertEqual(t, conn.Out(), "(nil)")
|
||||
be.Err(t, err, nil)
|
||||
be.Equal(t, res.(core.Value), core.Value(nil))
|
||||
be.Equal(t, conn.Out(), "(nil)")
|
||||
})
|
||||
}
|
||||
|
||||
@@ -3,9 +3,9 @@ package list
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/nalgeon/be"
|
||||
"github.com/nalgeon/redka/internal/core"
|
||||
"github.com/nalgeon/redka/internal/redis"
|
||||
"github.com/nalgeon/redka/internal/testx"
|
||||
)
|
||||
|
||||
func TestRPushParse(t *testing.T) {
|
||||
@@ -39,12 +39,12 @@ func TestRPushParse(t *testing.T) {
|
||||
for _, test := range tests {
|
||||
t.Run(test.cmd, func(t *testing.T) {
|
||||
cmd, err := redis.Parse(ParseRPush, test.cmd)
|
||||
testx.AssertEqual(t, err, test.err)
|
||||
be.Equal(t, err, test.err)
|
||||
if err == nil {
|
||||
testx.AssertEqual(t, cmd.key, test.want.key)
|
||||
testx.AssertEqual(t, cmd.elem, test.want.elem)
|
||||
be.Equal(t, cmd.key, test.want.key)
|
||||
be.Equal(t, cmd.elem, test.want.elem)
|
||||
} else {
|
||||
testx.AssertEqual(t, cmd, test.want)
|
||||
be.Equal(t, cmd, test.want)
|
||||
}
|
||||
})
|
||||
}
|
||||
@@ -52,70 +52,66 @@ func TestRPushParse(t *testing.T) {
|
||||
|
||||
func TestRPushExec(t *testing.T) {
|
||||
t.Run("empty list", func(t *testing.T) {
|
||||
db, red := getDB(t)
|
||||
defer db.Close()
|
||||
red := getRedka(t)
|
||||
|
||||
cmd := redis.MustParse(ParseRPush, "rpush key elem")
|
||||
conn := redis.NewFakeConn()
|
||||
res, err := cmd.Run(conn, red)
|
||||
testx.AssertNoErr(t, err)
|
||||
testx.AssertEqual(t, res, 1)
|
||||
testx.AssertEqual(t, conn.Out(), "1")
|
||||
be.Err(t, err, nil)
|
||||
be.Equal(t, res, 1)
|
||||
be.Equal(t, conn.Out(), "1")
|
||||
|
||||
elem, _ := db.List().Get("key", 0)
|
||||
testx.AssertEqual(t, elem.String(), "elem")
|
||||
elem, _ := red.List().Get("key", 0)
|
||||
be.Equal(t, elem.String(), "elem")
|
||||
})
|
||||
t.Run("add elem", func(t *testing.T) {
|
||||
db, red := getDB(t)
|
||||
defer db.Close()
|
||||
_, _ = db.List().PushBack("key", "one")
|
||||
red := getRedka(t)
|
||||
_, _ = red.List().PushBack("key", "one")
|
||||
|
||||
cmd := redis.MustParse(ParseRPush, "rpush key two")
|
||||
conn := redis.NewFakeConn()
|
||||
res, err := cmd.Run(conn, red)
|
||||
testx.AssertNoErr(t, err)
|
||||
testx.AssertEqual(t, res, 2)
|
||||
testx.AssertEqual(t, conn.Out(), "2")
|
||||
be.Err(t, err, nil)
|
||||
be.Equal(t, res, 2)
|
||||
be.Equal(t, conn.Out(), "2")
|
||||
|
||||
elem, _ := db.List().Get("key", 1)
|
||||
testx.AssertEqual(t, elem.String(), "two")
|
||||
elem, _ := red.List().Get("key", 1)
|
||||
be.Equal(t, elem.String(), "two")
|
||||
})
|
||||
t.Run("add miltiple", func(t *testing.T) {
|
||||
db, red := getDB(t)
|
||||
defer db.Close()
|
||||
red := getRedka(t)
|
||||
|
||||
{
|
||||
cmd := redis.MustParse(ParseRPush, "rpush key one")
|
||||
conn := redis.NewFakeConn()
|
||||
res, err := cmd.Run(conn, red)
|
||||
testx.AssertNoErr(t, err)
|
||||
testx.AssertEqual(t, res, 1)
|
||||
testx.AssertEqual(t, conn.Out(), "1")
|
||||
be.Err(t, err, nil)
|
||||
be.Equal(t, res, 1)
|
||||
be.Equal(t, conn.Out(), "1")
|
||||
}
|
||||
{
|
||||
cmd := redis.MustParse(ParseRPush, "rpush key two")
|
||||
conn := redis.NewFakeConn()
|
||||
res, err := cmd.Run(conn, red)
|
||||
testx.AssertNoErr(t, err)
|
||||
testx.AssertEqual(t, res, 2)
|
||||
testx.AssertEqual(t, conn.Out(), "2")
|
||||
be.Err(t, err, nil)
|
||||
be.Equal(t, res, 2)
|
||||
be.Equal(t, conn.Out(), "2")
|
||||
}
|
||||
|
||||
el0, _ := db.List().Get("key", 0)
|
||||
testx.AssertEqual(t, el0.String(), "one")
|
||||
el1, _ := db.List().Get("key", 1)
|
||||
testx.AssertEqual(t, el1.String(), "two")
|
||||
el0, _ := red.List().Get("key", 0)
|
||||
be.Equal(t, el0.String(), "one")
|
||||
el1, _ := red.List().Get("key", 1)
|
||||
be.Equal(t, el1.String(), "two")
|
||||
})
|
||||
t.Run("key type mismatch", func(t *testing.T) {
|
||||
db, red := getDB(t)
|
||||
defer db.Close()
|
||||
_ = db.Str().Set("key", "str")
|
||||
red := getRedka(t)
|
||||
_ = red.Str().Set("key", "str")
|
||||
|
||||
cmd := redis.MustParse(ParseRPush, "rpush key elem")
|
||||
conn := redis.NewFakeConn()
|
||||
res, err := cmd.Run(conn, red)
|
||||
testx.AssertErr(t, err, core.ErrKeyType)
|
||||
testx.AssertEqual(t, res, nil)
|
||||
testx.AssertEqual(t, conn.Out(), core.ErrKeyType.Error()+" (rpush)")
|
||||
be.Err(t, err, core.ErrKeyType)
|
||||
be.Equal(t, res, nil)
|
||||
be.Equal(t, conn.Out(), core.ErrKeyType.Error()+" (rpush)")
|
||||
})
|
||||
}
|
||||
|
||||
@@ -3,8 +3,8 @@ package server
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/nalgeon/be"
|
||||
"github.com/nalgeon/redka/internal/redis"
|
||||
"github.com/nalgeon/redka/internal/testx"
|
||||
)
|
||||
|
||||
func TestConfigParse(t *testing.T) {
|
||||
@@ -38,11 +38,11 @@ func TestConfigParse(t *testing.T) {
|
||||
for _, test := range tests {
|
||||
t.Run(test.cmd, func(t *testing.T) {
|
||||
cmd, err := redis.Parse(ParseConfig, test.cmd)
|
||||
testx.AssertEqual(t, err, test.err)
|
||||
be.Equal(t, err, test.err)
|
||||
if err == nil {
|
||||
testx.AssertEqual(t, cmd.subcmd, test.want.subcmd)
|
||||
be.Equal(t, cmd.subcmd, test.want.subcmd)
|
||||
} else {
|
||||
testx.AssertEqual(t, cmd, test.want)
|
||||
be.Equal(t, cmd, test.want)
|
||||
}
|
||||
})
|
||||
}
|
||||
@@ -50,14 +50,13 @@ func TestConfigParse(t *testing.T) {
|
||||
|
||||
func TestConfigExec(t *testing.T) {
|
||||
t.Run("config get", func(t *testing.T) {
|
||||
db, red := getDB(t)
|
||||
defer db.Close()
|
||||
red := getRedka(t)
|
||||
|
||||
cmd := redis.MustParse(ParseConfig, "config get *")
|
||||
conn := redis.NewFakeConn()
|
||||
res, err := cmd.Run(conn, red)
|
||||
testx.AssertNoErr(t, err)
|
||||
testx.AssertEqual(t, res, true)
|
||||
testx.AssertEqual(t, conn.Out(), "2,databases,1")
|
||||
be.Err(t, err, nil)
|
||||
be.Equal(t, res, true)
|
||||
be.Equal(t, conn.Out(), "2,databases,1")
|
||||
})
|
||||
}
|
||||
|
||||
@@ -3,8 +3,8 @@ package server
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/nalgeon/be"
|
||||
"github.com/nalgeon/redka/internal/redis"
|
||||
"github.com/nalgeon/redka/internal/testx"
|
||||
)
|
||||
|
||||
func TestDBSizeParse(t *testing.T) {
|
||||
@@ -25,9 +25,9 @@ func TestDBSizeParse(t *testing.T) {
|
||||
for _, test := range tests {
|
||||
t.Run(test.cmd, func(t *testing.T) {
|
||||
cmd, err := redis.Parse(ParseDBSize, test.cmd)
|
||||
testx.AssertEqual(t, err, test.err)
|
||||
be.Equal(t, err, test.err)
|
||||
if err != nil {
|
||||
testx.AssertEqual(t, cmd, DBSize{})
|
||||
be.Equal(t, cmd, DBSize{})
|
||||
}
|
||||
})
|
||||
}
|
||||
@@ -35,29 +35,26 @@ func TestDBSizeParse(t *testing.T) {
|
||||
|
||||
func TestDBSizeExec(t *testing.T) {
|
||||
t.Run("dbsize", func(t *testing.T) {
|
||||
db, red := getDB(t)
|
||||
defer db.Close()
|
||||
|
||||
_ = db.Str().Set("name", "alice")
|
||||
_ = db.Str().Set("age", 25)
|
||||
red := getRedka(t)
|
||||
_ = red.Str().Set("name", "alice")
|
||||
_ = red.Str().Set("age", 25)
|
||||
|
||||
cmd := redis.MustParse(ParseDBSize, "dbsize")
|
||||
conn := redis.NewFakeConn()
|
||||
res, err := cmd.Run(conn, red)
|
||||
testx.AssertNoErr(t, err)
|
||||
testx.AssertEqual(t, res, 2)
|
||||
testx.AssertEqual(t, conn.Out(), "2")
|
||||
be.Err(t, err, nil)
|
||||
be.Equal(t, res, 2)
|
||||
be.Equal(t, conn.Out(), "2")
|
||||
})
|
||||
|
||||
t.Run("empty", func(t *testing.T) {
|
||||
db, red := getDB(t)
|
||||
defer db.Close()
|
||||
red := getRedka(t)
|
||||
|
||||
cmd := redis.MustParse(ParseDBSize, "dbsize")
|
||||
conn := redis.NewFakeConn()
|
||||
res, err := cmd.Run(conn, red)
|
||||
testx.AssertNoErr(t, err)
|
||||
testx.AssertEqual(t, res, 0)
|
||||
testx.AssertEqual(t, conn.Out(), "0")
|
||||
be.Err(t, err, nil)
|
||||
be.Equal(t, res, 0)
|
||||
be.Equal(t, conn.Out(), "0")
|
||||
})
|
||||
}
|
||||
|
||||
@@ -4,8 +4,8 @@ import (
|
||||
"strings"
|
||||
"testing"
|
||||
|
||||
"github.com/nalgeon/be"
|
||||
"github.com/nalgeon/redka/internal/redis"
|
||||
"github.com/nalgeon/redka/internal/testx"
|
||||
)
|
||||
|
||||
func TestLolwutParse(t *testing.T) {
|
||||
@@ -30,9 +30,9 @@ func TestLolwutParse(t *testing.T) {
|
||||
for _, test := range tests {
|
||||
t.Run(test.cmd, func(t *testing.T) {
|
||||
cmd, err := redis.Parse(ParseLolwut, test.cmd)
|
||||
testx.AssertEqual(t, err, test.err)
|
||||
be.Equal(t, err, test.err)
|
||||
if err != nil {
|
||||
testx.AssertEqual(t, cmd, Lolwut{})
|
||||
be.Equal(t, cmd, Lolwut{})
|
||||
}
|
||||
})
|
||||
}
|
||||
@@ -40,24 +40,22 @@ func TestLolwutParse(t *testing.T) {
|
||||
|
||||
func TestLolwutExec(t *testing.T) {
|
||||
t.Run("lolwut", func(t *testing.T) {
|
||||
db, red := getDB(t)
|
||||
defer db.Close()
|
||||
red := getRedka(t)
|
||||
|
||||
cmd := redis.MustParse(ParseLolwut, "lolwut you ok?")
|
||||
conn := redis.NewFakeConn()
|
||||
_, err := cmd.Run(conn, red)
|
||||
testx.AssertNoErr(t, err)
|
||||
testx.AssertEqual(t, len(conn.Out()) >= 3, true)
|
||||
be.Err(t, err, nil)
|
||||
be.Equal(t, len(conn.Out()) >= 3, true)
|
||||
})
|
||||
|
||||
t.Run("empty", func(t *testing.T) {
|
||||
db, red := getDB(t)
|
||||
defer db.Close()
|
||||
red := getRedka(t)
|
||||
|
||||
cmd := redis.MustParse(ParseLolwut, "lolwut")
|
||||
conn := redis.NewFakeConn()
|
||||
_, err := cmd.Run(conn, red)
|
||||
testx.AssertNoErr(t, err)
|
||||
testx.AssertEqual(t, strings.HasPrefix(conn.Out(), "Ask me a question"), true)
|
||||
be.Err(t, err, nil)
|
||||
be.Equal(t, strings.HasPrefix(conn.Out(), "Ask me a question"), true)
|
||||
})
|
||||
}
|
||||
|
||||
@@ -3,15 +3,12 @@ package server
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/nalgeon/redka"
|
||||
"github.com/nalgeon/redka/internal/redis"
|
||||
"github.com/nalgeon/redka/internal/testx"
|
||||
)
|
||||
|
||||
func getDB(tb testing.TB) (*redka.DB, redis.Redka) {
|
||||
func getRedka(tb testing.TB) redis.Redka {
|
||||
tb.Helper()
|
||||
db, err := redka.Open("file:/data.db?vfs=memdb", nil)
|
||||
if err != nil {
|
||||
tb.Fatal(err)
|
||||
}
|
||||
return db, redis.RedkaDB(db)
|
||||
db := testx.OpenDB(tb)
|
||||
return redis.RedkaDB(db)
|
||||
}
|
||||
|
||||
@@ -3,9 +3,9 @@ package set
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/nalgeon/be"
|
||||
"github.com/nalgeon/redka/internal/core"
|
||||
"github.com/nalgeon/redka/internal/redis"
|
||||
"github.com/nalgeon/redka/internal/testx"
|
||||
)
|
||||
|
||||
func TestSAddParse(t *testing.T) {
|
||||
@@ -44,12 +44,12 @@ func TestSAddParse(t *testing.T) {
|
||||
for _, test := range tests {
|
||||
t.Run(test.cmd, func(t *testing.T) {
|
||||
cmd, err := redis.Parse(ParseSAdd, test.cmd)
|
||||
testx.AssertEqual(t, err, test.err)
|
||||
be.Equal(t, err, test.err)
|
||||
if err == nil {
|
||||
testx.AssertEqual(t, cmd.key, test.want.key)
|
||||
testx.AssertEqual(t, cmd.members, test.want.members)
|
||||
be.Equal(t, cmd.key, test.want.key)
|
||||
be.Equal(t, cmd.members, test.want.members)
|
||||
} else {
|
||||
testx.AssertEqual(t, cmd, test.want)
|
||||
be.Equal(t, cmd, test.want)
|
||||
}
|
||||
})
|
||||
}
|
||||
@@ -57,76 +57,71 @@ func TestSAddParse(t *testing.T) {
|
||||
|
||||
func TestSAddExec(t *testing.T) {
|
||||
t.Run("create single", func(t *testing.T) {
|
||||
db, red := getDB(t)
|
||||
defer db.Close()
|
||||
red := getRedka(t)
|
||||
|
||||
cmd := redis.MustParse(ParseSAdd, "sadd key one")
|
||||
conn := redis.NewFakeConn()
|
||||
res, err := cmd.Run(conn, red)
|
||||
testx.AssertNoErr(t, err)
|
||||
testx.AssertEqual(t, res, 1)
|
||||
testx.AssertEqual(t, conn.Out(), "1")
|
||||
be.Err(t, err, nil)
|
||||
be.Equal(t, res, 1)
|
||||
be.Equal(t, conn.Out(), "1")
|
||||
|
||||
items, _ := db.Set().Items("key")
|
||||
testx.AssertEqual(t, items, []core.Value{core.Value("one")})
|
||||
items, _ := red.Set().Items("key")
|
||||
be.Equal(t, items, []core.Value{core.Value("one")})
|
||||
})
|
||||
t.Run("create multiple", func(t *testing.T) {
|
||||
db, red := getDB(t)
|
||||
defer db.Close()
|
||||
red := getRedka(t)
|
||||
|
||||
cmd := redis.MustParse(ParseSAdd, "sadd key one two")
|
||||
conn := redis.NewFakeConn()
|
||||
res, err := cmd.Run(conn, red)
|
||||
testx.AssertNoErr(t, err)
|
||||
testx.AssertEqual(t, res, 2)
|
||||
testx.AssertEqual(t, conn.Out(), "2")
|
||||
be.Err(t, err, nil)
|
||||
be.Equal(t, res, 2)
|
||||
be.Equal(t, conn.Out(), "2")
|
||||
|
||||
items, _ := db.Set().Items("key")
|
||||
items, _ := red.Set().Items("key")
|
||||
sortValues(items)
|
||||
testx.AssertEqual(t, items, []core.Value{core.Value("one"), core.Value("two")})
|
||||
be.Equal(t, items, []core.Value{core.Value("one"), core.Value("two")})
|
||||
})
|
||||
t.Run("create/update", func(t *testing.T) {
|
||||
db, red := getDB(t)
|
||||
defer db.Close()
|
||||
_, _ = db.Set().Add("key", "one")
|
||||
red := getRedka(t)
|
||||
_, _ = red.Set().Add("key", "one")
|
||||
|
||||
cmd := redis.MustParse(ParseSAdd, "sadd key one two")
|
||||
conn := redis.NewFakeConn()
|
||||
res, err := cmd.Run(conn, red)
|
||||
testx.AssertNoErr(t, err)
|
||||
testx.AssertEqual(t, res, 1)
|
||||
testx.AssertEqual(t, conn.Out(), "1")
|
||||
be.Err(t, err, nil)
|
||||
be.Equal(t, res, 1)
|
||||
be.Equal(t, conn.Out(), "1")
|
||||
|
||||
items, _ := db.Set().Items("key")
|
||||
items, _ := red.Set().Items("key")
|
||||
sortValues(items)
|
||||
testx.AssertEqual(t, items, []core.Value{core.Value("one"), core.Value("two")})
|
||||
be.Equal(t, items, []core.Value{core.Value("one"), core.Value("two")})
|
||||
})
|
||||
t.Run("update multiple", func(t *testing.T) {
|
||||
db, red := getDB(t)
|
||||
defer db.Close()
|
||||
_, _ = db.Set().Add("key", "one", "two")
|
||||
red := getRedka(t)
|
||||
_, _ = red.Set().Add("key", "one", "two")
|
||||
|
||||
cmd := redis.MustParse(ParseSAdd, "sadd key one two")
|
||||
conn := redis.NewFakeConn()
|
||||
res, err := cmd.Run(conn, red)
|
||||
testx.AssertNoErr(t, err)
|
||||
testx.AssertEqual(t, res, 0)
|
||||
testx.AssertEqual(t, conn.Out(), "0")
|
||||
be.Err(t, err, nil)
|
||||
be.Equal(t, res, 0)
|
||||
be.Equal(t, conn.Out(), "0")
|
||||
|
||||
items, _ := db.Set().Items("key")
|
||||
items, _ := red.Set().Items("key")
|
||||
sortValues(items)
|
||||
testx.AssertEqual(t, items, []core.Value{core.Value("one"), core.Value("two")})
|
||||
be.Equal(t, items, []core.Value{core.Value("one"), core.Value("two")})
|
||||
})
|
||||
t.Run("key type mismatch", func(t *testing.T) {
|
||||
db, red := getDB(t)
|
||||
defer db.Close()
|
||||
_ = db.Str().Set("key", "value")
|
||||
red := getRedka(t)
|
||||
_ = red.Str().Set("key", "value")
|
||||
|
||||
cmd := redis.MustParse(ParseSAdd, "sadd key one")
|
||||
conn := redis.NewFakeConn()
|
||||
res, err := cmd.Run(conn, red)
|
||||
testx.AssertErr(t, err, core.ErrKeyType)
|
||||
testx.AssertEqual(t, res, nil)
|
||||
testx.AssertEqual(t, conn.Out(), core.ErrKeyType.Error()+" (sadd)")
|
||||
be.Err(t, err, core.ErrKeyType)
|
||||
be.Equal(t, res, nil)
|
||||
be.Equal(t, conn.Out(), core.ErrKeyType.Error()+" (sadd)")
|
||||
})
|
||||
}
|
||||
|
||||
@@ -3,8 +3,8 @@ package set
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/nalgeon/be"
|
||||
"github.com/nalgeon/redka/internal/redis"
|
||||
"github.com/nalgeon/redka/internal/testx"
|
||||
)
|
||||
|
||||
func TestSCardParse(t *testing.T) {
|
||||
@@ -33,11 +33,11 @@ func TestSCardParse(t *testing.T) {
|
||||
for _, test := range tests {
|
||||
t.Run(test.cmd, func(t *testing.T) {
|
||||
cmd, err := redis.Parse(ParseSCard, test.cmd)
|
||||
testx.AssertEqual(t, err, test.err)
|
||||
be.Equal(t, err, test.err)
|
||||
if err == nil {
|
||||
testx.AssertEqual(t, cmd.key, test.want.key)
|
||||
be.Equal(t, cmd.key, test.want.key)
|
||||
} else {
|
||||
testx.AssertEqual(t, cmd, test.want)
|
||||
be.Equal(t, cmd, test.want)
|
||||
}
|
||||
})
|
||||
}
|
||||
@@ -45,51 +45,47 @@ func TestSCardParse(t *testing.T) {
|
||||
|
||||
func TestSCardExec(t *testing.T) {
|
||||
t.Run("card", func(t *testing.T) {
|
||||
db, red := getDB(t)
|
||||
defer db.Close()
|
||||
_, _ = db.Set().Add("key", "one", "two")
|
||||
red := getRedka(t)
|
||||
_, _ = red.Set().Add("key", "one", "two")
|
||||
|
||||
cmd := redis.MustParse(ParseSCard, "scard key")
|
||||
conn := redis.NewFakeConn()
|
||||
res, err := cmd.Run(conn, red)
|
||||
testx.AssertNoErr(t, err)
|
||||
testx.AssertEqual(t, res, 2)
|
||||
testx.AssertEqual(t, conn.Out(), "2")
|
||||
be.Err(t, err, nil)
|
||||
be.Equal(t, res, 2)
|
||||
be.Equal(t, conn.Out(), "2")
|
||||
})
|
||||
t.Run("empty", func(t *testing.T) {
|
||||
db, red := getDB(t)
|
||||
defer db.Close()
|
||||
_, _ = db.Set().Add("key", "one")
|
||||
_, _ = db.Set().Delete("key", "one")
|
||||
red := getRedka(t)
|
||||
_, _ = red.Set().Add("key", "one")
|
||||
_, _ = red.Set().Delete("key", "one")
|
||||
|
||||
cmd := redis.MustParse(ParseSCard, "scard key")
|
||||
conn := redis.NewFakeConn()
|
||||
res, err := cmd.Run(conn, red)
|
||||
testx.AssertNoErr(t, err)
|
||||
testx.AssertEqual(t, res, 0)
|
||||
testx.AssertEqual(t, conn.Out(), "0")
|
||||
be.Err(t, err, nil)
|
||||
be.Equal(t, res, 0)
|
||||
be.Equal(t, conn.Out(), "0")
|
||||
})
|
||||
t.Run("key not found", func(t *testing.T) {
|
||||
db, red := getDB(t)
|
||||
defer db.Close()
|
||||
red := getRedka(t)
|
||||
|
||||
cmd := redis.MustParse(ParseSCard, "scard key")
|
||||
conn := redis.NewFakeConn()
|
||||
res, err := cmd.Run(conn, red)
|
||||
testx.AssertNoErr(t, err)
|
||||
testx.AssertEqual(t, res, 0)
|
||||
testx.AssertEqual(t, conn.Out(), "0")
|
||||
be.Err(t, err, nil)
|
||||
be.Equal(t, res, 0)
|
||||
be.Equal(t, conn.Out(), "0")
|
||||
})
|
||||
t.Run("key type mismatch", func(t *testing.T) {
|
||||
db, red := getDB(t)
|
||||
defer db.Close()
|
||||
_ = db.Str().Set("key", "value")
|
||||
red := getRedka(t)
|
||||
_ = red.Str().Set("key", "value")
|
||||
|
||||
cmd := redis.MustParse(ParseSCard, "scard key")
|
||||
conn := redis.NewFakeConn()
|
||||
res, err := cmd.Run(conn, red)
|
||||
testx.AssertNoErr(t, err)
|
||||
testx.AssertEqual(t, res, 0)
|
||||
testx.AssertEqual(t, conn.Out(), "0")
|
||||
be.Err(t, err, nil)
|
||||
be.Equal(t, res, 0)
|
||||
be.Equal(t, conn.Out(), "0")
|
||||
})
|
||||
}
|
||||
|
||||
@@ -3,9 +3,9 @@ package set
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/nalgeon/be"
|
||||
"github.com/nalgeon/redka/internal/core"
|
||||
"github.com/nalgeon/redka/internal/redis"
|
||||
"github.com/nalgeon/redka/internal/testx"
|
||||
)
|
||||
|
||||
func TestSDiffParse(t *testing.T) {
|
||||
@@ -34,11 +34,11 @@ func TestSDiffParse(t *testing.T) {
|
||||
for _, test := range tests {
|
||||
t.Run(test.cmd, func(t *testing.T) {
|
||||
cmd, err := redis.Parse(ParseSDiff, test.cmd)
|
||||
testx.AssertEqual(t, err, test.err)
|
||||
be.Equal(t, err, test.err)
|
||||
if err == nil {
|
||||
testx.AssertEqual(t, cmd.keys, test.want.keys)
|
||||
be.Equal(t, cmd.keys, test.want.keys)
|
||||
} else {
|
||||
testx.AssertEqual(t, cmd, test.want)
|
||||
be.Equal(t, cmd, test.want)
|
||||
}
|
||||
})
|
||||
}
|
||||
@@ -46,105 +46,97 @@ func TestSDiffParse(t *testing.T) {
|
||||
|
||||
func TestSDiffExec(t *testing.T) {
|
||||
t.Run("non-empty", func(t *testing.T) {
|
||||
db, red := getDB(t)
|
||||
defer db.Close()
|
||||
_, _ = db.Set().Add("key1", "one", "two", "thr", "fiv")
|
||||
_, _ = db.Set().Add("key2", "two", "fou", "six")
|
||||
_, _ = db.Set().Add("key3", "thr", "six")
|
||||
red := getRedka(t)
|
||||
_, _ = red.Set().Add("key1", "one", "two", "thr", "fiv")
|
||||
_, _ = red.Set().Add("key2", "two", "fou", "six")
|
||||
_, _ = red.Set().Add("key3", "thr", "six")
|
||||
|
||||
cmd := redis.MustParse(ParseSDiff, "sdiff key1 key2 key3")
|
||||
conn := redis.NewFakeConn()
|
||||
res, err := cmd.Run(conn, red)
|
||||
testx.AssertNoErr(t, err)
|
||||
testx.AssertEqual(t, len(res.([]core.Value)), 2)
|
||||
testx.AssertEqual(t, conn.Out(), "2,fiv,one")
|
||||
be.Err(t, err, nil)
|
||||
be.Equal(t, len(res.([]core.Value)), 2)
|
||||
be.Equal(t, conn.Out(), "2,fiv,one", "2,one,fiv")
|
||||
})
|
||||
t.Run("no keys", func(t *testing.T) {
|
||||
db, red := getDB(t)
|
||||
defer db.Close()
|
||||
red := getRedka(t)
|
||||
|
||||
cmd := redis.MustParse(ParseSDiff, "sdiff key1")
|
||||
conn := redis.NewFakeConn()
|
||||
res, err := cmd.Run(conn, red)
|
||||
testx.AssertNoErr(t, err)
|
||||
testx.AssertEqual(t, len(res.([]core.Value)), 0)
|
||||
testx.AssertEqual(t, conn.Out(), "0")
|
||||
be.Err(t, err, nil)
|
||||
be.Equal(t, len(res.([]core.Value)), 0)
|
||||
be.Equal(t, conn.Out(), "0")
|
||||
})
|
||||
t.Run("single key", func(t *testing.T) {
|
||||
db, red := getDB(t)
|
||||
defer db.Close()
|
||||
_, _ = db.Set().Add("key1", "one", "two", "thr")
|
||||
red := getRedka(t)
|
||||
_, _ = red.Set().Add("key1", "one", "two", "thr")
|
||||
|
||||
cmd := redis.MustParse(ParseSDiff, "sdiff key1")
|
||||
conn := redis.NewFakeConn()
|
||||
res, err := cmd.Run(conn, red)
|
||||
testx.AssertNoErr(t, err)
|
||||
testx.AssertEqual(t, len(res.([]core.Value)), 3)
|
||||
testx.AssertEqual(t, conn.Out(), "3,one,thr,two")
|
||||
be.Err(t, err, nil)
|
||||
be.Equal(t, len(res.([]core.Value)), 3)
|
||||
be.Equal(t, conn.Out(), "3,one,thr,two", "3,one,two,thr")
|
||||
})
|
||||
t.Run("empty", func(t *testing.T) {
|
||||
db, red := getDB(t)
|
||||
defer db.Close()
|
||||
_, _ = db.Set().Add("key1", "one", "two")
|
||||
_, _ = db.Set().Add("key2", "one", "fou")
|
||||
_, _ = db.Set().Add("key3", "two", "fiv")
|
||||
red := getRedka(t)
|
||||
_, _ = red.Set().Add("key1", "one", "two")
|
||||
_, _ = red.Set().Add("key2", "one", "fou")
|
||||
_, _ = red.Set().Add("key3", "two", "fiv")
|
||||
|
||||
cmd := redis.MustParse(ParseSDiff, "sdiff key1 key2 key3")
|
||||
conn := redis.NewFakeConn()
|
||||
res, err := cmd.Run(conn, red)
|
||||
testx.AssertNoErr(t, err)
|
||||
testx.AssertEqual(t, len(res.([]core.Value)), 0)
|
||||
testx.AssertEqual(t, conn.Out(), "0")
|
||||
be.Err(t, err, nil)
|
||||
be.Equal(t, len(res.([]core.Value)), 0)
|
||||
be.Equal(t, conn.Out(), "0")
|
||||
})
|
||||
t.Run("first not found", func(t *testing.T) {
|
||||
db, red := getDB(t)
|
||||
defer db.Close()
|
||||
_, _ = db.Set().Add("key2", "two")
|
||||
_, _ = db.Set().Add("key3", "thr")
|
||||
red := getRedka(t)
|
||||
_, _ = red.Set().Add("key2", "two")
|
||||
_, _ = red.Set().Add("key3", "thr")
|
||||
|
||||
cmd := redis.MustParse(ParseSDiff, "sdiff key1 key2 key3")
|
||||
conn := redis.NewFakeConn()
|
||||
res, err := cmd.Run(conn, red)
|
||||
testx.AssertNoErr(t, err)
|
||||
testx.AssertEqual(t, len(res.([]core.Value)), 0)
|
||||
testx.AssertEqual(t, conn.Out(), "0")
|
||||
be.Err(t, err, nil)
|
||||
be.Equal(t, len(res.([]core.Value)), 0)
|
||||
be.Equal(t, conn.Out(), "0")
|
||||
})
|
||||
t.Run("rest not found", func(t *testing.T) {
|
||||
db, red := getDB(t)
|
||||
defer db.Close()
|
||||
_, _ = db.Set().Add("key1", "one")
|
||||
_, _ = db.Set().Add("key2", "two")
|
||||
red := getRedka(t)
|
||||
_, _ = red.Set().Add("key1", "one")
|
||||
_, _ = red.Set().Add("key2", "two")
|
||||
|
||||
cmd := redis.MustParse(ParseSDiff, "sdiff key1 key2 key3")
|
||||
conn := redis.NewFakeConn()
|
||||
res, err := cmd.Run(conn, red)
|
||||
testx.AssertNoErr(t, err)
|
||||
testx.AssertEqual(t, len(res.([]core.Value)), 1)
|
||||
testx.AssertEqual(t, conn.Out(), "1,one")
|
||||
be.Err(t, err, nil)
|
||||
be.Equal(t, len(res.([]core.Value)), 1)
|
||||
be.Equal(t, conn.Out(), "1,one")
|
||||
})
|
||||
t.Run("all not found", func(t *testing.T) {
|
||||
db, red := getDB(t)
|
||||
defer db.Close()
|
||||
red := getRedka(t)
|
||||
|
||||
cmd := redis.MustParse(ParseSDiff, "sdiff key1 key2 key3")
|
||||
conn := redis.NewFakeConn()
|
||||
res, err := cmd.Run(conn, red)
|
||||
testx.AssertNoErr(t, err)
|
||||
testx.AssertEqual(t, len(res.([]core.Value)), 0)
|
||||
testx.AssertEqual(t, conn.Out(), "0")
|
||||
be.Err(t, err, nil)
|
||||
be.Equal(t, len(res.([]core.Value)), 0)
|
||||
be.Equal(t, conn.Out(), "0")
|
||||
})
|
||||
t.Run("key type mismatch", func(t *testing.T) {
|
||||
db, red := getDB(t)
|
||||
defer db.Close()
|
||||
_, _ = db.Set().Add("key1", "one")
|
||||
_ = db.Str().Set("key2", "two")
|
||||
_, _ = db.Set().Add("key3", "thr")
|
||||
red := getRedka(t)
|
||||
_, _ = red.Set().Add("key1", "one")
|
||||
_ = red.Str().Set("key2", "two")
|
||||
_, _ = red.Set().Add("key3", "thr")
|
||||
|
||||
cmd := redis.MustParse(ParseSDiff, "sdiff key1 key2 key3")
|
||||
conn := redis.NewFakeConn()
|
||||
res, err := cmd.Run(conn, red)
|
||||
testx.AssertNoErr(t, err)
|
||||
testx.AssertEqual(t, len(res.([]core.Value)), 1)
|
||||
testx.AssertEqual(t, conn.Out(), "1,one")
|
||||
be.Err(t, err, nil)
|
||||
be.Equal(t, len(res.([]core.Value)), 1)
|
||||
be.Equal(t, conn.Out(), "1,one")
|
||||
})
|
||||
}
|
||||
|
||||
@@ -3,9 +3,9 @@ package set
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/nalgeon/be"
|
||||
"github.com/nalgeon/redka/internal/core"
|
||||
"github.com/nalgeon/redka/internal/redis"
|
||||
"github.com/nalgeon/redka/internal/testx"
|
||||
)
|
||||
|
||||
func TestSDiffStoreParse(t *testing.T) {
|
||||
@@ -39,12 +39,12 @@ func TestSDiffStoreParse(t *testing.T) {
|
||||
for _, test := range tests {
|
||||
t.Run(test.cmd, func(t *testing.T) {
|
||||
cmd, err := redis.Parse(ParseSDiffStore, test.cmd)
|
||||
testx.AssertEqual(t, err, test.err)
|
||||
be.Equal(t, err, test.err)
|
||||
if err == nil {
|
||||
testx.AssertEqual(t, cmd.dest, test.want.dest)
|
||||
testx.AssertEqual(t, cmd.keys, test.want.keys)
|
||||
be.Equal(t, cmd.dest, test.want.dest)
|
||||
be.Equal(t, cmd.keys, test.want.keys)
|
||||
} else {
|
||||
testx.AssertEqual(t, cmd, test.want)
|
||||
be.Equal(t, cmd, test.want)
|
||||
}
|
||||
})
|
||||
}
|
||||
@@ -52,139 +52,131 @@ func TestSDiffStoreParse(t *testing.T) {
|
||||
|
||||
func TestSDiffStoreExec(t *testing.T) {
|
||||
t.Run("store", func(t *testing.T) {
|
||||
db, red := getDB(t)
|
||||
defer db.Close()
|
||||
_, _ = db.Set().Add("key1", "one", "two", "thr", "fiv")
|
||||
_, _ = db.Set().Add("key2", "two", "fou", "six")
|
||||
_, _ = db.Set().Add("key3", "thr", "six")
|
||||
red := getRedka(t)
|
||||
_, _ = red.Set().Add("key1", "one", "two", "thr", "fiv")
|
||||
_, _ = red.Set().Add("key2", "two", "fou", "six")
|
||||
_, _ = red.Set().Add("key3", "thr", "six")
|
||||
|
||||
cmd := redis.MustParse(ParseSDiffStore, "sdiffstore dest key1 key2 key3")
|
||||
conn := redis.NewFakeConn()
|
||||
res, err := cmd.Run(conn, red)
|
||||
testx.AssertNoErr(t, err)
|
||||
testx.AssertEqual(t, res, 2)
|
||||
testx.AssertEqual(t, conn.Out(), "2")
|
||||
be.Err(t, err, nil)
|
||||
be.Equal(t, res, 2)
|
||||
be.Equal(t, conn.Out(), "2")
|
||||
|
||||
items, _ := db.Set().Items("dest")
|
||||
items, _ := red.Set().Items("dest")
|
||||
sortValues(items)
|
||||
testx.AssertEqual(t, items, []core.Value{core.Value("fiv"), core.Value("one")})
|
||||
be.Equal(t, items, []core.Value{core.Value("fiv"), core.Value("one")})
|
||||
})
|
||||
t.Run("rewrite dest", func(t *testing.T) {
|
||||
db, red := getDB(t)
|
||||
defer db.Close()
|
||||
_, _ = db.Set().Add("key1", "one")
|
||||
_, _ = db.Set().Add("key2", "two")
|
||||
_, _ = db.Set().Add("dest", "old")
|
||||
red := getRedka(t)
|
||||
_, _ = red.Set().Add("key1", "one")
|
||||
_, _ = red.Set().Add("key2", "two")
|
||||
_, _ = red.Set().Add("dest", "old")
|
||||
|
||||
cmd := redis.MustParse(ParseSDiffStore, "sdiffstore dest key1 key2")
|
||||
conn := redis.NewFakeConn()
|
||||
res, err := cmd.Run(conn, red)
|
||||
testx.AssertNoErr(t, err)
|
||||
testx.AssertEqual(t, res, 1)
|
||||
testx.AssertEqual(t, conn.Out(), "1")
|
||||
be.Err(t, err, nil)
|
||||
be.Equal(t, res, 1)
|
||||
be.Equal(t, conn.Out(), "1")
|
||||
|
||||
items, _ := db.Set().Items("dest")
|
||||
testx.AssertEqual(t, items, []core.Value{core.Value("one")})
|
||||
items, _ := red.Set().Items("dest")
|
||||
be.Equal(t, items, []core.Value{core.Value("one")})
|
||||
})
|
||||
t.Run("single key", func(t *testing.T) {
|
||||
db, red := getDB(t)
|
||||
defer db.Close()
|
||||
_, _ = db.Set().Add("key1", "one", "two")
|
||||
_, _ = db.Set().Add("dest", "old")
|
||||
red := getRedka(t)
|
||||
_, _ = red.Set().Add("key1", "one", "two")
|
||||
_, _ = red.Set().Add("dest", "old")
|
||||
|
||||
cmd := redis.MustParse(ParseSDiffStore, "sdiffstore dest key1")
|
||||
conn := redis.NewFakeConn()
|
||||
res, err := cmd.Run(conn, red)
|
||||
testx.AssertNoErr(t, err)
|
||||
testx.AssertEqual(t, res, 2)
|
||||
testx.AssertEqual(t, conn.Out(), "2")
|
||||
be.Err(t, err, nil)
|
||||
be.Equal(t, res, 2)
|
||||
be.Equal(t, conn.Out(), "2")
|
||||
|
||||
items, _ := db.Set().Items("dest")
|
||||
items, _ := red.Set().Items("dest")
|
||||
sortValues(items)
|
||||
testx.AssertEqual(t, items, []core.Value{core.Value("one"), core.Value("two")})
|
||||
be.Equal(t, items, []core.Value{core.Value("one"), core.Value("two")})
|
||||
})
|
||||
t.Run("empty", func(t *testing.T) {
|
||||
db, red := getDB(t)
|
||||
defer db.Close()
|
||||
_, _ = db.Set().Add("key1", "one")
|
||||
_, _ = db.Set().Add("key2", "one")
|
||||
_, _ = db.Set().Add("dest", "old")
|
||||
red := getRedka(t)
|
||||
_, _ = red.Set().Add("key1", "one")
|
||||
_, _ = red.Set().Add("key2", "one")
|
||||
_, _ = red.Set().Add("dest", "old")
|
||||
|
||||
cmd := redis.MustParse(ParseSDiffStore, "sdiffstore dest key1 key2")
|
||||
conn := redis.NewFakeConn()
|
||||
res, err := cmd.Run(conn, red)
|
||||
testx.AssertNoErr(t, err)
|
||||
testx.AssertEqual(t, res, 0)
|
||||
testx.AssertEqual(t, conn.Out(), "0")
|
||||
be.Err(t, err, nil)
|
||||
be.Equal(t, res, 0)
|
||||
be.Equal(t, conn.Out(), "0")
|
||||
|
||||
items, _ := db.Set().Items("dest")
|
||||
testx.AssertEqual(t, items, []core.Value(nil))
|
||||
items, _ := red.Set().Items("dest")
|
||||
be.Equal(t, items, []core.Value(nil))
|
||||
})
|
||||
t.Run("first not found", func(t *testing.T) {
|
||||
db, red := getDB(t)
|
||||
defer db.Close()
|
||||
_, _ = db.Set().Add("key2", "two")
|
||||
_, _ = db.Set().Add("key3", "thr")
|
||||
_, _ = db.Set().Add("dest", "old")
|
||||
red := getRedka(t)
|
||||
_, _ = red.Set().Add("key2", "two")
|
||||
_, _ = red.Set().Add("key3", "thr")
|
||||
_, _ = red.Set().Add("dest", "old")
|
||||
|
||||
cmd := redis.MustParse(ParseSDiffStore, "sdiffstore dest key1 key2 key3")
|
||||
conn := redis.NewFakeConn()
|
||||
res, err := cmd.Run(conn, red)
|
||||
testx.AssertNoErr(t, err)
|
||||
testx.AssertEqual(t, res, 0)
|
||||
testx.AssertEqual(t, conn.Out(), "0")
|
||||
be.Err(t, err, nil)
|
||||
be.Equal(t, res, 0)
|
||||
be.Equal(t, conn.Out(), "0")
|
||||
|
||||
items, _ := db.Set().Items("dest")
|
||||
testx.AssertEqual(t, items, []core.Value(nil))
|
||||
items, _ := red.Set().Items("dest")
|
||||
be.Equal(t, items, []core.Value(nil))
|
||||
})
|
||||
t.Run("rest not found", func(t *testing.T) {
|
||||
db, red := getDB(t)
|
||||
defer db.Close()
|
||||
_, _ = db.Set().Add("key1", "one")
|
||||
_, _ = db.Set().Add("key2", "two")
|
||||
red := getRedka(t)
|
||||
_, _ = red.Set().Add("key1", "one")
|
||||
_, _ = red.Set().Add("key2", "two")
|
||||
|
||||
cmd := redis.MustParse(ParseSDiffStore, "sdiffstore dest key1 key2 key3")
|
||||
conn := redis.NewFakeConn()
|
||||
res, err := cmd.Run(conn, red)
|
||||
testx.AssertNoErr(t, err)
|
||||
testx.AssertEqual(t, res, 1)
|
||||
testx.AssertEqual(t, conn.Out(), "1")
|
||||
be.Err(t, err, nil)
|
||||
be.Equal(t, res, 1)
|
||||
be.Equal(t, conn.Out(), "1")
|
||||
|
||||
items, _ := db.Set().Items("dest")
|
||||
testx.AssertEqual(t, items, []core.Value{core.Value("one")})
|
||||
items, _ := red.Set().Items("dest")
|
||||
be.Equal(t, items, []core.Value{core.Value("one")})
|
||||
})
|
||||
t.Run("source key type mismatch", func(t *testing.T) {
|
||||
db, red := getDB(t)
|
||||
defer db.Close()
|
||||
_, _ = db.Set().Add("key1", "one")
|
||||
_, _ = db.Set().Add("key2", "two")
|
||||
_ = db.Str().Set("key3", "thr")
|
||||
red := getRedka(t)
|
||||
_, _ = red.Set().Add("key1", "one")
|
||||
_, _ = red.Set().Add("key2", "two")
|
||||
_ = red.Str().Set("key3", "thr")
|
||||
|
||||
cmd := redis.MustParse(ParseSDiffStore, "sdiffstore dest key1 key2 key3")
|
||||
conn := redis.NewFakeConn()
|
||||
res, err := cmd.Run(conn, red)
|
||||
testx.AssertNoErr(t, err)
|
||||
testx.AssertEqual(t, res, 1)
|
||||
testx.AssertEqual(t, conn.Out(), "1")
|
||||
be.Err(t, err, nil)
|
||||
be.Equal(t, res, 1)
|
||||
be.Equal(t, conn.Out(), "1")
|
||||
|
||||
items, _ := db.Set().Items("dest")
|
||||
testx.AssertEqual(t, items, []core.Value{core.Value("one")})
|
||||
items, _ := red.Set().Items("dest")
|
||||
be.Equal(t, items, []core.Value{core.Value("one")})
|
||||
})
|
||||
t.Run("dest key type mismatch", func(t *testing.T) {
|
||||
db, red := getDB(t)
|
||||
defer db.Close()
|
||||
_, _ = db.Set().Add("key1", "one")
|
||||
_, _ = db.Set().Add("key2", "two")
|
||||
_ = db.Str().Set("dest", "old")
|
||||
red := getRedka(t)
|
||||
_, _ = red.Set().Add("key1", "one")
|
||||
_, _ = red.Set().Add("key2", "two")
|
||||
_ = red.Str().Set("dest", "old")
|
||||
|
||||
cmd := redis.MustParse(ParseSDiffStore, "sdiffstore dest key1 key2")
|
||||
conn := redis.NewFakeConn()
|
||||
res, err := cmd.Run(conn, red)
|
||||
testx.AssertErr(t, err, core.ErrKeyType)
|
||||
testx.AssertEqual(t, res, nil)
|
||||
testx.AssertEqual(t, conn.Out(), core.ErrKeyType.Error()+" (sdiffstore)")
|
||||
be.Err(t, err, core.ErrKeyType)
|
||||
be.Equal(t, res, nil)
|
||||
be.Equal(t, conn.Out(), core.ErrKeyType.Error()+" (sdiffstore)")
|
||||
|
||||
sval, _ := db.Str().Get("dest")
|
||||
testx.AssertEqual(t, sval, core.Value("old"))
|
||||
sval, _ := red.Str().Get("dest")
|
||||
be.Equal(t, sval, core.Value("old"))
|
||||
})
|
||||
}
|
||||
|
||||
@@ -5,18 +5,15 @@ import (
|
||||
"sort"
|
||||
"testing"
|
||||
|
||||
"github.com/nalgeon/redka"
|
||||
"github.com/nalgeon/redka/internal/core"
|
||||
"github.com/nalgeon/redka/internal/redis"
|
||||
"github.com/nalgeon/redka/internal/testx"
|
||||
)
|
||||
|
||||
func getDB(tb testing.TB) (*redka.DB, redis.Redka) {
|
||||
func getRedka(tb testing.TB) redis.Redka {
|
||||
tb.Helper()
|
||||
db, err := redka.Open("file:/data.db?vfs=memdb", nil)
|
||||
if err != nil {
|
||||
tb.Fatal(err)
|
||||
}
|
||||
return db, redis.RedkaDB(db)
|
||||
db := testx.OpenDB(tb)
|
||||
return redis.RedkaDB(db)
|
||||
}
|
||||
|
||||
func sortValues(vals []core.Value) {
|
||||
|
||||
@@ -3,9 +3,9 @@ package set
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/nalgeon/be"
|
||||
"github.com/nalgeon/redka/internal/core"
|
||||
"github.com/nalgeon/redka/internal/redis"
|
||||
"github.com/nalgeon/redka/internal/testx"
|
||||
)
|
||||
|
||||
func TestSInterParse(t *testing.T) {
|
||||
@@ -34,11 +34,11 @@ func TestSInterParse(t *testing.T) {
|
||||
for _, test := range tests {
|
||||
t.Run(test.cmd, func(t *testing.T) {
|
||||
cmd, err := redis.Parse(ParseSInter, test.cmd)
|
||||
testx.AssertEqual(t, err, test.err)
|
||||
be.Equal(t, err, test.err)
|
||||
if err == nil {
|
||||
testx.AssertEqual(t, cmd.keys, test.want.keys)
|
||||
be.Equal(t, cmd.keys, test.want.keys)
|
||||
} else {
|
||||
testx.AssertEqual(t, cmd, test.want)
|
||||
be.Equal(t, cmd, test.want)
|
||||
}
|
||||
})
|
||||
}
|
||||
@@ -46,92 +46,85 @@ func TestSInterParse(t *testing.T) {
|
||||
|
||||
func TestSInterExec(t *testing.T) {
|
||||
t.Run("non-empty", func(t *testing.T) {
|
||||
db, red := getDB(t)
|
||||
defer db.Close()
|
||||
_, _ = db.Set().Add("key1", "one", "two", "thr")
|
||||
_, _ = db.Set().Add("key2", "two", "thr", "fou")
|
||||
_, _ = db.Set().Add("key3", "one", "two", "thr", "fou")
|
||||
red := getRedka(t)
|
||||
_, _ = red.Set().Add("key1", "one", "two", "thr")
|
||||
_, _ = red.Set().Add("key2", "two", "thr", "fou")
|
||||
_, _ = red.Set().Add("key3", "one", "two", "thr", "fou")
|
||||
|
||||
cmd := redis.MustParse(ParseSInter, "sinter key1 key2 key3")
|
||||
conn := redis.NewFakeConn()
|
||||
res, err := cmd.Run(conn, red)
|
||||
testx.AssertNoErr(t, err)
|
||||
testx.AssertEqual(t, len(res.([]core.Value)), 2)
|
||||
testx.AssertEqual(t, conn.Out(), "2,thr,two")
|
||||
be.Err(t, err, nil)
|
||||
be.Equal(t, len(res.([]core.Value)), 2)
|
||||
be.Equal(t, conn.Out(), "2,thr,two")
|
||||
})
|
||||
t.Run("no keys", func(t *testing.T) {
|
||||
db, red := getDB(t)
|
||||
defer db.Close()
|
||||
red := getRedka(t)
|
||||
|
||||
cmd := redis.MustParse(ParseSInter, "sinter key1")
|
||||
conn := redis.NewFakeConn()
|
||||
res, err := cmd.Run(conn, red)
|
||||
testx.AssertNoErr(t, err)
|
||||
testx.AssertEqual(t, len(res.([]core.Value)), 0)
|
||||
testx.AssertEqual(t, conn.Out(), "0")
|
||||
be.Err(t, err, nil)
|
||||
be.Equal(t, len(res.([]core.Value)), 0)
|
||||
be.Equal(t, conn.Out(), "0")
|
||||
})
|
||||
t.Run("single key", func(t *testing.T) {
|
||||
db, red := getDB(t)
|
||||
defer db.Close()
|
||||
_, _ = db.Set().Add("key1", "one", "two", "thr")
|
||||
red := getRedka(t)
|
||||
_, _ = red.Set().Add("key1", "one", "two", "thr")
|
||||
|
||||
cmd := redis.MustParse(ParseSInter, "sinter key1")
|
||||
conn := redis.NewFakeConn()
|
||||
res, err := cmd.Run(conn, red)
|
||||
testx.AssertNoErr(t, err)
|
||||
testx.AssertEqual(t, len(res.([]core.Value)), 3)
|
||||
testx.AssertEqual(t, conn.Out(), "3,one,thr,two")
|
||||
be.Err(t, err, nil)
|
||||
be.Equal(t, len(res.([]core.Value)), 3)
|
||||
be.Equal(t, conn.Out(), "3,one,thr,two")
|
||||
})
|
||||
t.Run("empty", func(t *testing.T) {
|
||||
db, red := getDB(t)
|
||||
defer db.Close()
|
||||
_, _ = db.Set().Add("key1", "one", "two")
|
||||
_, _ = db.Set().Add("key2", "two", "thr")
|
||||
_, _ = db.Set().Add("key3", "thr", "fou")
|
||||
red := getRedka(t)
|
||||
_, _ = red.Set().Add("key1", "one", "two")
|
||||
_, _ = red.Set().Add("key2", "two", "thr")
|
||||
_, _ = red.Set().Add("key3", "thr", "fou")
|
||||
|
||||
cmd := redis.MustParse(ParseSInter, "sinter key1 key2 key3")
|
||||
conn := redis.NewFakeConn()
|
||||
res, err := cmd.Run(conn, red)
|
||||
testx.AssertNoErr(t, err)
|
||||
testx.AssertEqual(t, len(res.([]core.Value)), 0)
|
||||
testx.AssertEqual(t, conn.Out(), "0")
|
||||
be.Err(t, err, nil)
|
||||
be.Equal(t, len(res.([]core.Value)), 0)
|
||||
be.Equal(t, conn.Out(), "0")
|
||||
})
|
||||
t.Run("key not found", func(t *testing.T) {
|
||||
db, red := getDB(t)
|
||||
defer db.Close()
|
||||
_, _ = db.Set().Add("key1", "one")
|
||||
_, _ = db.Set().Add("key2", "one")
|
||||
red := getRedka(t)
|
||||
_, _ = red.Set().Add("key1", "one")
|
||||
_, _ = red.Set().Add("key2", "one")
|
||||
|
||||
cmd := redis.MustParse(ParseSInter, "sinter key1 key2 key3")
|
||||
conn := redis.NewFakeConn()
|
||||
res, err := cmd.Run(conn, red)
|
||||
testx.AssertNoErr(t, err)
|
||||
testx.AssertEqual(t, len(res.([]core.Value)), 0)
|
||||
testx.AssertEqual(t, conn.Out(), "0")
|
||||
be.Err(t, err, nil)
|
||||
be.Equal(t, len(res.([]core.Value)), 0)
|
||||
be.Equal(t, conn.Out(), "0")
|
||||
})
|
||||
t.Run("all not found", func(t *testing.T) {
|
||||
db, red := getDB(t)
|
||||
defer db.Close()
|
||||
red := getRedka(t)
|
||||
|
||||
cmd := redis.MustParse(ParseSInter, "sinter key1 key2 key3")
|
||||
conn := redis.NewFakeConn()
|
||||
res, err := cmd.Run(conn, red)
|
||||
testx.AssertNoErr(t, err)
|
||||
testx.AssertEqual(t, len(res.([]core.Value)), 0)
|
||||
testx.AssertEqual(t, conn.Out(), "0")
|
||||
be.Err(t, err, nil)
|
||||
be.Equal(t, len(res.([]core.Value)), 0)
|
||||
be.Equal(t, conn.Out(), "0")
|
||||
})
|
||||
t.Run("key type mismatch", func(t *testing.T) {
|
||||
db, red := getDB(t)
|
||||
defer db.Close()
|
||||
_, _ = db.Set().Add("key1", "one")
|
||||
_ = db.Str().Set("key2", "one")
|
||||
_, _ = db.Set().Add("key3", "one")
|
||||
red := getRedka(t)
|
||||
_, _ = red.Set().Add("key1", "one")
|
||||
_ = red.Str().Set("key2", "one")
|
||||
_, _ = red.Set().Add("key3", "one")
|
||||
|
||||
cmd := redis.MustParse(ParseSInter, "sinter key1 key2 key3")
|
||||
conn := redis.NewFakeConn()
|
||||
res, err := cmd.Run(conn, red)
|
||||
testx.AssertNoErr(t, err)
|
||||
testx.AssertEqual(t, len(res.([]core.Value)), 0)
|
||||
testx.AssertEqual(t, conn.Out(), "0")
|
||||
be.Err(t, err, nil)
|
||||
be.Equal(t, len(res.([]core.Value)), 0)
|
||||
be.Equal(t, conn.Out(), "0")
|
||||
})
|
||||
}
|
||||
|
||||
@@ -3,9 +3,9 @@ package set
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/nalgeon/be"
|
||||
"github.com/nalgeon/redka/internal/core"
|
||||
"github.com/nalgeon/redka/internal/redis"
|
||||
"github.com/nalgeon/redka/internal/testx"
|
||||
)
|
||||
|
||||
func TestSInterStoreParse(t *testing.T) {
|
||||
@@ -39,10 +39,10 @@ func TestSInterStoreParse(t *testing.T) {
|
||||
for _, test := range tests {
|
||||
t.Run(test.cmd, func(t *testing.T) {
|
||||
cmd, err := redis.Parse(ParseSInterStore, test.cmd)
|
||||
testx.AssertEqual(t, err, test.err)
|
||||
be.Equal(t, err, test.err)
|
||||
if err == nil {
|
||||
testx.AssertEqual(t, cmd.dest, test.want.dest)
|
||||
testx.AssertEqual(t, cmd.keys, test.want.keys)
|
||||
be.Equal(t, cmd.dest, test.want.dest)
|
||||
be.Equal(t, cmd.keys, test.want.keys)
|
||||
}
|
||||
})
|
||||
}
|
||||
@@ -50,123 +50,116 @@ func TestSInterStoreParse(t *testing.T) {
|
||||
|
||||
func TestSInterStoreExec(t *testing.T) {
|
||||
t.Run("store", func(t *testing.T) {
|
||||
db, red := getDB(t)
|
||||
defer db.Close()
|
||||
_, _ = db.Set().Add("key1", "one", "two", "thr")
|
||||
_, _ = db.Set().Add("key2", "two", "thr", "fou")
|
||||
_, _ = db.Set().Add("key3", "one", "two", "thr", "fou")
|
||||
red := getRedka(t)
|
||||
_, _ = red.Set().Add("key1", "one", "two", "thr")
|
||||
_, _ = red.Set().Add("key2", "two", "thr", "fou")
|
||||
_, _ = red.Set().Add("key3", "one", "two", "thr", "fou")
|
||||
|
||||
cmd := redis.MustParse(ParseSInterStore, "sinterstore dest key1 key2 key3")
|
||||
conn := redis.NewFakeConn()
|
||||
res, err := cmd.Run(conn, red)
|
||||
testx.AssertNoErr(t, err)
|
||||
testx.AssertEqual(t, res, 2)
|
||||
testx.AssertEqual(t, conn.Out(), "2")
|
||||
be.Err(t, err, nil)
|
||||
be.Equal(t, res, 2)
|
||||
be.Equal(t, conn.Out(), "2")
|
||||
|
||||
items, _ := db.Set().Items("dest")
|
||||
items, _ := red.Set().Items("dest")
|
||||
sortValues(items)
|
||||
testx.AssertEqual(t, items, []core.Value{core.Value("thr"), core.Value("two")})
|
||||
be.Equal(t, items, []core.Value{core.Value("thr"), core.Value("two")})
|
||||
})
|
||||
t.Run("rewrite dest", func(t *testing.T) {
|
||||
db, red := getDB(t)
|
||||
defer db.Close()
|
||||
_, _ = db.Set().Add("key1", "one")
|
||||
_, _ = db.Set().Add("key2", "one")
|
||||
_, _ = db.Set().Add("dest", "old")
|
||||
red := getRedka(t)
|
||||
_, _ = red.Set().Add("key1", "one")
|
||||
_, _ = red.Set().Add("key2", "one")
|
||||
_, _ = red.Set().Add("dest", "old")
|
||||
|
||||
cmd := redis.MustParse(ParseSInterStore, "sinterstore dest key1 key2")
|
||||
conn := redis.NewFakeConn()
|
||||
res, err := cmd.Run(conn, red)
|
||||
testx.AssertNoErr(t, err)
|
||||
testx.AssertEqual(t, res, 1)
|
||||
testx.AssertEqual(t, conn.Out(), "1")
|
||||
be.Err(t, err, nil)
|
||||
be.Equal(t, res, 1)
|
||||
be.Equal(t, conn.Out(), "1")
|
||||
|
||||
items, _ := db.Set().Items("dest")
|
||||
testx.AssertEqual(t, items, []core.Value{core.Value("one")})
|
||||
items, _ := red.Set().Items("dest")
|
||||
be.Equal(t, items, []core.Value{core.Value("one")})
|
||||
})
|
||||
t.Run("single key", func(t *testing.T) {
|
||||
db, red := getDB(t)
|
||||
defer db.Close()
|
||||
_, _ = db.Set().Add("key1", "one", "two")
|
||||
_, _ = db.Set().Add("dest", "old")
|
||||
red := getRedka(t)
|
||||
_, _ = red.Set().Add("key1", "one", "two")
|
||||
_, _ = red.Set().Add("dest", "old")
|
||||
|
||||
cmd := redis.MustParse(ParseSInterStore, "sinterstore dest key1")
|
||||
conn := redis.NewFakeConn()
|
||||
res, err := cmd.Run(conn, red)
|
||||
testx.AssertNoErr(t, err)
|
||||
testx.AssertEqual(t, res, 2)
|
||||
testx.AssertEqual(t, conn.Out(), "2")
|
||||
be.Err(t, err, nil)
|
||||
be.Equal(t, res, 2)
|
||||
be.Equal(t, conn.Out(), "2")
|
||||
|
||||
items, _ := db.Set().Items("dest")
|
||||
items, _ := red.Set().Items("dest")
|
||||
sortValues(items)
|
||||
testx.AssertEqual(t, items, []core.Value{core.Value("one"), core.Value("two")})
|
||||
be.Equal(t, items, []core.Value{core.Value("one"), core.Value("two")})
|
||||
})
|
||||
t.Run("empty", func(t *testing.T) {
|
||||
db, red := getDB(t)
|
||||
defer db.Close()
|
||||
_, _ = db.Set().Add("key1", "one")
|
||||
_, _ = db.Set().Add("key2", "two")
|
||||
_, _ = db.Set().Add("dest", "old")
|
||||
red := getRedka(t)
|
||||
_, _ = red.Set().Add("key1", "one")
|
||||
_, _ = red.Set().Add("key2", "two")
|
||||
_, _ = red.Set().Add("dest", "old")
|
||||
|
||||
cmd := redis.MustParse(ParseSInterStore, "sinterstore dest key1 key2")
|
||||
conn := redis.NewFakeConn()
|
||||
res, err := cmd.Run(conn, red)
|
||||
testx.AssertNoErr(t, err)
|
||||
testx.AssertEqual(t, res, 0)
|
||||
testx.AssertEqual(t, conn.Out(), "0")
|
||||
be.Err(t, err, nil)
|
||||
be.Equal(t, res, 0)
|
||||
be.Equal(t, conn.Out(), "0")
|
||||
|
||||
items, _ := db.Set().Items("dest")
|
||||
testx.AssertEqual(t, items, []core.Value(nil))
|
||||
items, _ := red.Set().Items("dest")
|
||||
be.Equal(t, items, []core.Value(nil))
|
||||
})
|
||||
t.Run("source key not found", func(t *testing.T) {
|
||||
db, red := getDB(t)
|
||||
defer db.Close()
|
||||
_, _ = db.Set().Add("key1", "one")
|
||||
_, _ = db.Set().Add("key2", "one")
|
||||
_, _ = db.Set().Add("dest", "old")
|
||||
red := getRedka(t)
|
||||
_, _ = red.Set().Add("key1", "one")
|
||||
_, _ = red.Set().Add("key2", "one")
|
||||
_, _ = red.Set().Add("dest", "old")
|
||||
|
||||
cmd := redis.MustParse(ParseSInterStore, "sinterstore dest key1 key2 key3")
|
||||
conn := redis.NewFakeConn()
|
||||
res, err := cmd.Run(conn, red)
|
||||
testx.AssertNoErr(t, err)
|
||||
testx.AssertEqual(t, res, 0)
|
||||
testx.AssertEqual(t, conn.Out(), "0")
|
||||
be.Err(t, err, nil)
|
||||
be.Equal(t, res, 0)
|
||||
be.Equal(t, conn.Out(), "0")
|
||||
|
||||
items, _ := db.Set().Items("dest")
|
||||
testx.AssertEqual(t, items, []core.Value(nil))
|
||||
items, _ := red.Set().Items("dest")
|
||||
be.Equal(t, items, []core.Value(nil))
|
||||
})
|
||||
t.Run("source key type mismatch", func(t *testing.T) {
|
||||
db, red := getDB(t)
|
||||
defer db.Close()
|
||||
_, _ = db.Set().Add("key1", "one")
|
||||
_, _ = db.Set().Add("key2", "one")
|
||||
_ = db.Str().Set("key3", "one")
|
||||
red := getRedka(t)
|
||||
_, _ = red.Set().Add("key1", "one")
|
||||
_, _ = red.Set().Add("key2", "one")
|
||||
_ = red.Str().Set("key3", "one")
|
||||
|
||||
cmd := redis.MustParse(ParseSInterStore, "sinterstore dest key1 key2 key3")
|
||||
conn := redis.NewFakeConn()
|
||||
res, err := cmd.Run(conn, red)
|
||||
testx.AssertNoErr(t, err)
|
||||
testx.AssertEqual(t, res, 0)
|
||||
testx.AssertEqual(t, conn.Out(), "0")
|
||||
be.Err(t, err, nil)
|
||||
be.Equal(t, res, 0)
|
||||
be.Equal(t, conn.Out(), "0")
|
||||
|
||||
items, _ := db.Set().Items("dest")
|
||||
testx.AssertEqual(t, items, []core.Value(nil))
|
||||
items, _ := red.Set().Items("dest")
|
||||
be.Equal(t, items, []core.Value(nil))
|
||||
})
|
||||
t.Run("dest key type mismatch", func(t *testing.T) {
|
||||
db, red := getDB(t)
|
||||
defer db.Close()
|
||||
_, _ = db.Set().Add("key1", "one")
|
||||
_, _ = db.Set().Add("key2", "one")
|
||||
_ = db.Str().Set("dest", "old")
|
||||
red := getRedka(t)
|
||||
_, _ = red.Set().Add("key1", "one")
|
||||
_, _ = red.Set().Add("key2", "one")
|
||||
_ = red.Str().Set("dest", "old")
|
||||
|
||||
cmd := redis.MustParse(ParseSInterStore, "sinterstore dest key1 key2")
|
||||
conn := redis.NewFakeConn()
|
||||
res, err := cmd.Run(conn, red)
|
||||
testx.AssertErr(t, err, core.ErrKeyType)
|
||||
testx.AssertEqual(t, res, nil)
|
||||
testx.AssertEqual(t, conn.Out(), core.ErrKeyType.Error()+" (sinterstore)")
|
||||
be.Err(t, err, core.ErrKeyType)
|
||||
be.Equal(t, res, nil)
|
||||
be.Equal(t, conn.Out(), core.ErrKeyType.Error()+" (sinterstore)")
|
||||
|
||||
sval, _ := db.Str().Get("dest")
|
||||
testx.AssertEqual(t, sval, core.Value("old"))
|
||||
sval, _ := red.Str().Get("dest")
|
||||
be.Equal(t, sval, core.Value("old"))
|
||||
})
|
||||
}
|
||||
|
||||
@@ -3,8 +3,8 @@ package set
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/nalgeon/be"
|
||||
"github.com/nalgeon/redka/internal/redis"
|
||||
"github.com/nalgeon/redka/internal/testx"
|
||||
)
|
||||
|
||||
func TestSIsMemberParse(t *testing.T) {
|
||||
@@ -38,12 +38,12 @@ func TestSIsMemberParse(t *testing.T) {
|
||||
for _, test := range tests {
|
||||
t.Run(test.cmd, func(t *testing.T) {
|
||||
cmd, err := redis.Parse(ParseSIsMember, test.cmd)
|
||||
testx.AssertEqual(t, err, test.err)
|
||||
be.Equal(t, err, test.err)
|
||||
if err == nil {
|
||||
testx.AssertEqual(t, cmd.key, test.want.key)
|
||||
testx.AssertEqual(t, cmd.member, test.want.member)
|
||||
be.Equal(t, cmd.key, test.want.key)
|
||||
be.Equal(t, cmd.member, test.want.member)
|
||||
} else {
|
||||
testx.AssertEqual(t, cmd, test.want)
|
||||
be.Equal(t, cmd, test.want)
|
||||
}
|
||||
})
|
||||
}
|
||||
@@ -51,50 +51,46 @@ func TestSIsMemberParse(t *testing.T) {
|
||||
|
||||
func TestSIsMemberExec(t *testing.T) {
|
||||
t.Run("elem found", func(t *testing.T) {
|
||||
db, red := getDB(t)
|
||||
defer db.Close()
|
||||
_, _ = db.Set().Add("key", "one")
|
||||
red := getRedka(t)
|
||||
_, _ = red.Set().Add("key", "one")
|
||||
|
||||
cmd := redis.MustParse(ParseSIsMember, "sismember key one")
|
||||
conn := redis.NewFakeConn()
|
||||
res, err := cmd.Run(conn, red)
|
||||
testx.AssertNoErr(t, err)
|
||||
testx.AssertEqual(t, res, true)
|
||||
testx.AssertEqual(t, conn.Out(), "1")
|
||||
be.Err(t, err, nil)
|
||||
be.Equal(t, res, true)
|
||||
be.Equal(t, conn.Out(), "1")
|
||||
})
|
||||
t.Run("elem not found", func(t *testing.T) {
|
||||
db, red := getDB(t)
|
||||
defer db.Close()
|
||||
_, _ = db.Set().Add("key", "one")
|
||||
red := getRedka(t)
|
||||
_, _ = red.Set().Add("key", "one")
|
||||
|
||||
cmd := redis.MustParse(ParseSIsMember, "sismember key two")
|
||||
conn := redis.NewFakeConn()
|
||||
res, err := cmd.Run(conn, red)
|
||||
testx.AssertNoErr(t, err)
|
||||
testx.AssertEqual(t, res, false)
|
||||
testx.AssertEqual(t, conn.Out(), "0")
|
||||
be.Err(t, err, nil)
|
||||
be.Equal(t, res, false)
|
||||
be.Equal(t, conn.Out(), "0")
|
||||
})
|
||||
t.Run("key not found", func(t *testing.T) {
|
||||
db, red := getDB(t)
|
||||
defer db.Close()
|
||||
red := getRedka(t)
|
||||
|
||||
cmd := redis.MustParse(ParseSIsMember, "sismember key one")
|
||||
conn := redis.NewFakeConn()
|
||||
res, err := cmd.Run(conn, red)
|
||||
testx.AssertNoErr(t, err)
|
||||
testx.AssertEqual(t, res, false)
|
||||
testx.AssertEqual(t, conn.Out(), "0")
|
||||
be.Err(t, err, nil)
|
||||
be.Equal(t, res, false)
|
||||
be.Equal(t, conn.Out(), "0")
|
||||
})
|
||||
t.Run("key type mismatch", func(t *testing.T) {
|
||||
db, red := getDB(t)
|
||||
defer db.Close()
|
||||
_ = db.Str().Set("key", "one")
|
||||
red := getRedka(t)
|
||||
_ = red.Str().Set("key", "one")
|
||||
|
||||
cmd := redis.MustParse(ParseSIsMember, "sismember key one")
|
||||
conn := redis.NewFakeConn()
|
||||
res, err := cmd.Run(conn, red)
|
||||
testx.AssertNoErr(t, err)
|
||||
testx.AssertEqual(t, res, false)
|
||||
testx.AssertEqual(t, conn.Out(), "0")
|
||||
be.Err(t, err, nil)
|
||||
be.Equal(t, res, false)
|
||||
be.Equal(t, conn.Out(), "0")
|
||||
})
|
||||
}
|
||||
|
||||
@@ -3,9 +3,9 @@ package set
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/nalgeon/be"
|
||||
"github.com/nalgeon/redka/internal/core"
|
||||
"github.com/nalgeon/redka/internal/redis"
|
||||
"github.com/nalgeon/redka/internal/testx"
|
||||
)
|
||||
|
||||
func TestSMembersParse(t *testing.T) {
|
||||
@@ -34,11 +34,11 @@ func TestSMembersParse(t *testing.T) {
|
||||
for _, test := range tests {
|
||||
t.Run(test.cmd, func(t *testing.T) {
|
||||
cmd, err := redis.Parse(ParseSMembers, test.cmd)
|
||||
testx.AssertEqual(t, err, test.err)
|
||||
be.Equal(t, err, test.err)
|
||||
if err == nil {
|
||||
testx.AssertEqual(t, cmd.key, test.want.key)
|
||||
be.Equal(t, cmd.key, test.want.key)
|
||||
} else {
|
||||
testx.AssertEqual(t, cmd, test.want)
|
||||
be.Equal(t, cmd, test.want)
|
||||
}
|
||||
})
|
||||
}
|
||||
@@ -46,40 +46,35 @@ func TestSMembersParse(t *testing.T) {
|
||||
|
||||
func TestSMembersExec(t *testing.T) {
|
||||
t.Run("items", func(t *testing.T) {
|
||||
db, red := getDB(t)
|
||||
defer db.Close()
|
||||
_, _ = db.Set().Add("key", "one", "two", "thr")
|
||||
red := getRedka(t)
|
||||
_, _ = red.Set().Add("key", "one", "two", "thr")
|
||||
|
||||
cmd := redis.MustParse(ParseSMembers, "smembers key")
|
||||
conn := redis.NewFakeConn()
|
||||
res, err := cmd.Run(conn, red)
|
||||
testx.AssertNoErr(t, err)
|
||||
testx.AssertEqual(t, res, []core.Value{
|
||||
core.Value("one"), core.Value("thr"), core.Value("two"),
|
||||
})
|
||||
testx.AssertEqual(t, conn.Out(), "3,one,thr,two")
|
||||
be.Err(t, err, nil)
|
||||
be.Equal(t, len(res.([]core.Value)), 3)
|
||||
be.Equal(t, conn.Out(), "3,one,thr,two", "3,one,two,thr")
|
||||
})
|
||||
t.Run("key not found", func(t *testing.T) {
|
||||
db, red := getDB(t)
|
||||
defer db.Close()
|
||||
red := getRedka(t)
|
||||
|
||||
cmd := redis.MustParse(ParseSMembers, "smembers key")
|
||||
conn := redis.NewFakeConn()
|
||||
res, err := cmd.Run(conn, red)
|
||||
testx.AssertNoErr(t, err)
|
||||
testx.AssertEqual(t, res, []core.Value(nil))
|
||||
testx.AssertEqual(t, conn.Out(), "0")
|
||||
be.Err(t, err, nil)
|
||||
be.Equal(t, res.([]core.Value), []core.Value(nil))
|
||||
be.Equal(t, conn.Out(), "0")
|
||||
})
|
||||
t.Run("key type mismatch", func(t *testing.T) {
|
||||
db, red := getDB(t)
|
||||
defer db.Close()
|
||||
_ = db.Str().Set("key", "value")
|
||||
red := getRedka(t)
|
||||
_ = red.Str().Set("key", "value")
|
||||
|
||||
cmd := redis.MustParse(ParseSMembers, "smembers key")
|
||||
conn := redis.NewFakeConn()
|
||||
res, err := cmd.Run(conn, red)
|
||||
testx.AssertNoErr(t, err)
|
||||
testx.AssertEqual(t, res, []core.Value(nil))
|
||||
testx.AssertEqual(t, conn.Out(), "0")
|
||||
be.Err(t, err, nil)
|
||||
be.Equal(t, res.([]core.Value), []core.Value(nil))
|
||||
be.Equal(t, conn.Out(), "0")
|
||||
})
|
||||
}
|
||||
|
||||
@@ -3,9 +3,9 @@ package set
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/nalgeon/be"
|
||||
"github.com/nalgeon/redka/internal/core"
|
||||
"github.com/nalgeon/redka/internal/redis"
|
||||
"github.com/nalgeon/redka/internal/testx"
|
||||
)
|
||||
|
||||
func TestSMoveParse(t *testing.T) {
|
||||
@@ -39,13 +39,13 @@ func TestSMoveParse(t *testing.T) {
|
||||
for _, test := range tests {
|
||||
t.Run(test.cmd, func(t *testing.T) {
|
||||
cmd, err := redis.Parse(ParseSMove, test.cmd)
|
||||
testx.AssertEqual(t, err, test.err)
|
||||
be.Equal(t, err, test.err)
|
||||
if err == nil {
|
||||
testx.AssertEqual(t, cmd.src, test.want.src)
|
||||
testx.AssertEqual(t, cmd.dest, test.want.dest)
|
||||
testx.AssertEqual(t, cmd.member, test.want.member)
|
||||
be.Equal(t, cmd.src, test.want.src)
|
||||
be.Equal(t, cmd.dest, test.want.dest)
|
||||
be.Equal(t, cmd.member, test.want.member)
|
||||
} else {
|
||||
testx.AssertEqual(t, cmd, test.want)
|
||||
be.Equal(t, cmd, test.want)
|
||||
}
|
||||
})
|
||||
}
|
||||
@@ -53,109 +53,103 @@ func TestSMoveParse(t *testing.T) {
|
||||
|
||||
func TestSMoveExec(t *testing.T) {
|
||||
t.Run("move", func(t *testing.T) {
|
||||
db, red := getDB(t)
|
||||
defer db.Close()
|
||||
_, _ = db.Set().Add("src", "one", "two")
|
||||
_, _ = db.Set().Add("dest", "thr", "fou")
|
||||
red := getRedka(t)
|
||||
_, _ = red.Set().Add("src", "one", "two")
|
||||
_, _ = red.Set().Add("dest", "thr", "fou")
|
||||
|
||||
cmd := redis.MustParse(ParseSMove, "smove src dest one")
|
||||
conn := redis.NewFakeConn()
|
||||
res, err := cmd.Run(conn, red)
|
||||
testx.AssertNoErr(t, err)
|
||||
testx.AssertEqual(t, res, 1)
|
||||
testx.AssertEqual(t, conn.Out(), "1")
|
||||
be.Err(t, err, nil)
|
||||
be.Equal(t, res, 1)
|
||||
be.Equal(t, conn.Out(), "1")
|
||||
|
||||
sone, _ := db.Set().Exists("src", "one")
|
||||
testx.AssertEqual(t, sone, false)
|
||||
done, _ := db.Set().Exists("dest", "one")
|
||||
testx.AssertEqual(t, done, true)
|
||||
sone, _ := red.Set().Exists("src", "one")
|
||||
be.Equal(t, sone, false)
|
||||
done, _ := red.Set().Exists("dest", "one")
|
||||
be.Equal(t, done, true)
|
||||
})
|
||||
t.Run("dest not found", func(t *testing.T) {
|
||||
db, red := getDB(t)
|
||||
defer db.Close()
|
||||
_, _ = db.Set().Add("src", "one", "two")
|
||||
red := getRedka(t)
|
||||
_, _ = red.Set().Add("src", "one", "two")
|
||||
|
||||
cmd := redis.MustParse(ParseSMove, "smove src dest one")
|
||||
conn := redis.NewFakeConn()
|
||||
res, err := cmd.Run(conn, red)
|
||||
testx.AssertNoErr(t, err)
|
||||
testx.AssertEqual(t, res, 1)
|
||||
testx.AssertEqual(t, conn.Out(), "1")
|
||||
be.Err(t, err, nil)
|
||||
be.Equal(t, res, 1)
|
||||
be.Equal(t, conn.Out(), "1")
|
||||
|
||||
sone, _ := db.Set().Exists("src", "one")
|
||||
testx.AssertEqual(t, sone, false)
|
||||
done, _ := db.Set().Exists("dest", "one")
|
||||
testx.AssertEqual(t, done, true)
|
||||
sone, _ := red.Set().Exists("src", "one")
|
||||
be.Equal(t, sone, false)
|
||||
done, _ := red.Set().Exists("dest", "one")
|
||||
be.Equal(t, done, true)
|
||||
})
|
||||
t.Run("src elem not found", func(t *testing.T) {
|
||||
db, red := getDB(t)
|
||||
defer db.Close()
|
||||
_, _ = db.Set().Add("src", "two")
|
||||
_, _ = db.Set().Add("dest", "thr", "fou")
|
||||
red := getRedka(t)
|
||||
_, _ = red.Set().Add("src", "two")
|
||||
_, _ = red.Set().Add("dest", "thr", "fou")
|
||||
|
||||
cmd := redis.MustParse(ParseSMove, "smove src dest one")
|
||||
conn := redis.NewFakeConn()
|
||||
res, err := cmd.Run(conn, red)
|
||||
testx.AssertNoErr(t, err)
|
||||
testx.AssertEqual(t, res, 0)
|
||||
testx.AssertEqual(t, conn.Out(), "0")
|
||||
be.Err(t, err, nil)
|
||||
be.Equal(t, res, 0)
|
||||
be.Equal(t, conn.Out(), "0")
|
||||
|
||||
sone, _ := db.Set().Exists("src", "one")
|
||||
testx.AssertEqual(t, sone, false)
|
||||
done, _ := db.Set().Exists("dest", "one")
|
||||
testx.AssertEqual(t, done, false)
|
||||
sone, _ := red.Set().Exists("src", "one")
|
||||
be.Equal(t, sone, false)
|
||||
done, _ := red.Set().Exists("dest", "one")
|
||||
be.Equal(t, done, false)
|
||||
})
|
||||
t.Run("src key not found", func(t *testing.T) {
|
||||
db, red := getDB(t)
|
||||
defer db.Close()
|
||||
_, _ = db.Set().Add("dest", "thr", "fou")
|
||||
red := getRedka(t)
|
||||
_, _ = red.Set().Add("dest", "thr", "fou")
|
||||
|
||||
cmd := redis.MustParse(ParseSMove, "smove src dest one")
|
||||
conn := redis.NewFakeConn()
|
||||
res, err := cmd.Run(conn, red)
|
||||
testx.AssertNoErr(t, err)
|
||||
testx.AssertEqual(t, res, 0)
|
||||
testx.AssertEqual(t, conn.Out(), "0")
|
||||
be.Err(t, err, nil)
|
||||
be.Equal(t, res, 0)
|
||||
be.Equal(t, conn.Out(), "0")
|
||||
|
||||
sone, _ := db.Set().Exists("src", "one")
|
||||
testx.AssertEqual(t, sone, false)
|
||||
done, _ := db.Set().Exists("dest", "one")
|
||||
testx.AssertEqual(t, done, false)
|
||||
sone, _ := red.Set().Exists("src", "one")
|
||||
be.Equal(t, sone, false)
|
||||
done, _ := red.Set().Exists("dest", "one")
|
||||
be.Equal(t, done, false)
|
||||
})
|
||||
t.Run("dest type mismatch", func(t *testing.T) {
|
||||
db, red := getDB(t)
|
||||
defer db.Close()
|
||||
_, _ = db.Set().Add("src", "one", "two")
|
||||
_ = db.Str().Set("dest", "str")
|
||||
red := getRedka(t)
|
||||
_, _ = red.Set().Add("src", "one", "two")
|
||||
_ = red.Str().Set("dest", "str")
|
||||
|
||||
cmd := redis.MustParse(ParseSMove, "smove src dest one")
|
||||
conn := redis.NewFakeConn()
|
||||
res, err := cmd.Run(conn, red)
|
||||
testx.AssertErr(t, err, core.ErrKeyType)
|
||||
testx.AssertEqual(t, res, nil)
|
||||
testx.AssertEqual(t, conn.Out(), core.ErrKeyType.Error()+" (smove)")
|
||||
be.Err(t, err, core.ErrKeyType)
|
||||
be.Equal(t, res, nil)
|
||||
be.Equal(t, conn.Out(), core.ErrKeyType.Error()+" (smove)")
|
||||
|
||||
sone, _ := db.Set().Exists("src", "one")
|
||||
testx.AssertEqual(t, sone, true)
|
||||
done, _ := db.Set().Exists("dest", "one")
|
||||
testx.AssertEqual(t, done, false)
|
||||
sone, _ := red.Set().Exists("src", "one")
|
||||
be.Equal(t, sone, true)
|
||||
done, _ := red.Set().Exists("dest", "one")
|
||||
be.Equal(t, done, false)
|
||||
})
|
||||
t.Run("src type mismatch", func(t *testing.T) {
|
||||
db, red := getDB(t)
|
||||
defer db.Close()
|
||||
_ = db.Str().Set("src", "one")
|
||||
_, _ = db.Set().Add("dest", "thr", "fou")
|
||||
red := getRedka(t)
|
||||
_ = red.Str().Set("src", "one")
|
||||
_, _ = red.Set().Add("dest", "thr", "fou")
|
||||
|
||||
cmd := redis.MustParse(ParseSMove, "smove src dest one")
|
||||
conn := redis.NewFakeConn()
|
||||
res, err := cmd.Run(conn, red)
|
||||
testx.AssertNoErr(t, err)
|
||||
testx.AssertEqual(t, res, 0)
|
||||
testx.AssertEqual(t, conn.Out(), "0")
|
||||
be.Err(t, err, nil)
|
||||
be.Equal(t, res, 0)
|
||||
be.Equal(t, conn.Out(), "0")
|
||||
|
||||
sone, _ := db.Set().Exists("src", "one")
|
||||
testx.AssertEqual(t, sone, false)
|
||||
done, _ := db.Set().Exists("dest", "one")
|
||||
testx.AssertEqual(t, done, false)
|
||||
sone, _ := red.Set().Exists("src", "one")
|
||||
be.Equal(t, sone, false)
|
||||
done, _ := red.Set().Exists("dest", "one")
|
||||
be.Equal(t, done, false)
|
||||
})
|
||||
}
|
||||
|
||||
@@ -3,9 +3,9 @@ package set
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/nalgeon/be"
|
||||
"github.com/nalgeon/redka/internal/core"
|
||||
"github.com/nalgeon/redka/internal/redis"
|
||||
"github.com/nalgeon/redka/internal/testx"
|
||||
)
|
||||
|
||||
func TestSPopParse(t *testing.T) {
|
||||
@@ -34,11 +34,11 @@ func TestSPopParse(t *testing.T) {
|
||||
for _, test := range tests {
|
||||
t.Run(test.cmd, func(t *testing.T) {
|
||||
cmd, err := redis.Parse(ParseSPop, test.cmd)
|
||||
testx.AssertEqual(t, err, test.err)
|
||||
be.Equal(t, err, test.err)
|
||||
if err == nil {
|
||||
testx.AssertEqual(t, cmd.key, test.want.key)
|
||||
be.Equal(t, cmd.key, test.want.key)
|
||||
} else {
|
||||
testx.AssertEqual(t, cmd, test.want)
|
||||
be.Equal(t, cmd, test.want)
|
||||
}
|
||||
})
|
||||
}
|
||||
@@ -46,43 +46,40 @@ func TestSPopParse(t *testing.T) {
|
||||
|
||||
func TestSPopExec(t *testing.T) {
|
||||
t.Run("pop", func(t *testing.T) {
|
||||
db, red := getDB(t)
|
||||
defer db.Close()
|
||||
_, _ = db.Set().Add("key", "one", "two", "thr")
|
||||
red := getRedka(t)
|
||||
_, _ = red.Set().Add("key", "one", "two", "thr")
|
||||
|
||||
cmd := redis.MustParse(ParseSPop, "spop key")
|
||||
conn := redis.NewFakeConn()
|
||||
res, err := cmd.Run(conn, red)
|
||||
testx.AssertNoErr(t, err)
|
||||
be.Err(t, err, nil)
|
||||
s := res.(core.Value).String()
|
||||
testx.AssertEqual(t, s == "one" || s == "two" || s == "thr", true)
|
||||
be.Equal(t, s == "one" || s == "two" || s == "thr", true)
|
||||
s = conn.Out()
|
||||
testx.AssertEqual(t, s == "one" || s == "two" || s == "thr", true)
|
||||
be.Equal(t, s == "one" || s == "two" || s == "thr", true)
|
||||
|
||||
slen, _ := db.Set().Len("key")
|
||||
testx.AssertEqual(t, slen, 2)
|
||||
slen, _ := red.Set().Len("key")
|
||||
be.Equal(t, slen, 2)
|
||||
})
|
||||
t.Run("key not found", func(t *testing.T) {
|
||||
db, red := getDB(t)
|
||||
defer db.Close()
|
||||
red := getRedka(t)
|
||||
|
||||
cmd := redis.MustParse(ParseSPop, "spop key")
|
||||
conn := redis.NewFakeConn()
|
||||
res, err := cmd.Run(conn, red)
|
||||
testx.AssertNoErr(t, err)
|
||||
testx.AssertEqual(t, res, core.Value(nil))
|
||||
testx.AssertEqual(t, conn.Out(), "(nil)")
|
||||
be.Err(t, err, nil)
|
||||
be.Equal(t, res.(core.Value), core.Value(nil))
|
||||
be.Equal(t, conn.Out(), "(nil)")
|
||||
})
|
||||
t.Run("key type mismatch", func(t *testing.T) {
|
||||
db, red := getDB(t)
|
||||
defer db.Close()
|
||||
_ = db.Str().Set("key", "value")
|
||||
red := getRedka(t)
|
||||
_ = red.Str().Set("key", "value")
|
||||
|
||||
cmd := redis.MustParse(ParseSPop, "spop key")
|
||||
conn := redis.NewFakeConn()
|
||||
res, err := cmd.Run(conn, red)
|
||||
testx.AssertNoErr(t, err)
|
||||
testx.AssertEqual(t, res, core.Value(nil))
|
||||
testx.AssertEqual(t, conn.Out(), "(nil)")
|
||||
be.Err(t, err, nil)
|
||||
be.Equal(t, res.(core.Value), core.Value(nil))
|
||||
be.Equal(t, conn.Out(), "(nil)")
|
||||
})
|
||||
}
|
||||
|
||||
@@ -3,9 +3,9 @@ package set
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/nalgeon/be"
|
||||
"github.com/nalgeon/redka/internal/core"
|
||||
"github.com/nalgeon/redka/internal/redis"
|
||||
"github.com/nalgeon/redka/internal/testx"
|
||||
)
|
||||
|
||||
func TestSRandMemberParse(t *testing.T) {
|
||||
@@ -34,11 +34,11 @@ func TestSRandMemberParse(t *testing.T) {
|
||||
for _, test := range tests {
|
||||
t.Run(test.cmd, func(t *testing.T) {
|
||||
cmd, err := redis.Parse(ParseSRandMember, test.cmd)
|
||||
testx.AssertEqual(t, err, test.err)
|
||||
be.Equal(t, err, test.err)
|
||||
if err == nil {
|
||||
testx.AssertEqual(t, cmd.key, test.want.key)
|
||||
be.Equal(t, cmd.key, test.want.key)
|
||||
} else {
|
||||
testx.AssertEqual(t, cmd, test.want)
|
||||
be.Equal(t, cmd, test.want)
|
||||
}
|
||||
})
|
||||
}
|
||||
@@ -46,40 +46,37 @@ func TestSRandMemberParse(t *testing.T) {
|
||||
|
||||
func TestSRandMemberExec(t *testing.T) {
|
||||
t.Run("random", func(t *testing.T) {
|
||||
db, red := getDB(t)
|
||||
defer db.Close()
|
||||
_, _ = db.Set().Add("key", "one", "two", "thr")
|
||||
red := getRedka(t)
|
||||
_, _ = red.Set().Add("key", "one", "two", "thr")
|
||||
|
||||
cmd := redis.MustParse(ParseSRandMember, "srandmember key")
|
||||
conn := redis.NewFakeConn()
|
||||
res, err := cmd.Run(conn, red)
|
||||
testx.AssertNoErr(t, err)
|
||||
be.Err(t, err, nil)
|
||||
s := res.(core.Value).String()
|
||||
testx.AssertEqual(t, s == "one" || s == "two" || s == "thr", true)
|
||||
be.Equal(t, s == "one" || s == "two" || s == "thr", true)
|
||||
s = conn.Out()
|
||||
testx.AssertEqual(t, s == "one" || s == "two" || s == "thr", true)
|
||||
be.Equal(t, s == "one" || s == "two" || s == "thr", true)
|
||||
})
|
||||
t.Run("key not found", func(t *testing.T) {
|
||||
db, red := getDB(t)
|
||||
defer db.Close()
|
||||
red := getRedka(t)
|
||||
|
||||
cmd := redis.MustParse(ParseSRandMember, "srandmember key")
|
||||
conn := redis.NewFakeConn()
|
||||
res, err := cmd.Run(conn, red)
|
||||
testx.AssertNoErr(t, err)
|
||||
testx.AssertEqual(t, res, core.Value(nil))
|
||||
testx.AssertEqual(t, conn.Out(), "(nil)")
|
||||
be.Err(t, err, nil)
|
||||
be.Equal(t, res.(core.Value), core.Value(nil))
|
||||
be.Equal(t, conn.Out(), "(nil)")
|
||||
})
|
||||
t.Run("key type mismatch", func(t *testing.T) {
|
||||
db, red := getDB(t)
|
||||
defer db.Close()
|
||||
_ = db.Str().Set("key", "value")
|
||||
red := getRedka(t)
|
||||
_ = red.Str().Set("key", "value")
|
||||
|
||||
cmd := redis.MustParse(ParseSRandMember, "srandmember key")
|
||||
conn := redis.NewFakeConn()
|
||||
res, err := cmd.Run(conn, red)
|
||||
testx.AssertNoErr(t, err)
|
||||
testx.AssertEqual(t, res, core.Value(nil))
|
||||
testx.AssertEqual(t, conn.Out(), "(nil)")
|
||||
be.Err(t, err, nil)
|
||||
be.Equal(t, res.(core.Value), core.Value(nil))
|
||||
be.Equal(t, conn.Out(), "(nil)")
|
||||
})
|
||||
}
|
||||
|
||||
@@ -3,9 +3,9 @@ package set
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/nalgeon/be"
|
||||
"github.com/nalgeon/redka/internal/core"
|
||||
"github.com/nalgeon/redka/internal/redis"
|
||||
"github.com/nalgeon/redka/internal/testx"
|
||||
)
|
||||
|
||||
func TestSRemParse(t *testing.T) {
|
||||
@@ -44,12 +44,12 @@ func TestSRemParse(t *testing.T) {
|
||||
for _, test := range tests {
|
||||
t.Run(test.cmd, func(t *testing.T) {
|
||||
cmd, err := redis.Parse(ParseSRem, test.cmd)
|
||||
testx.AssertEqual(t, err, test.err)
|
||||
be.Equal(t, err, test.err)
|
||||
if err == nil {
|
||||
testx.AssertEqual(t, cmd.key, test.want.key)
|
||||
testx.AssertEqual(t, cmd.members, test.want.members)
|
||||
be.Equal(t, cmd.key, test.want.key)
|
||||
be.Equal(t, cmd.members, test.want.members)
|
||||
} else {
|
||||
testx.AssertEqual(t, cmd, test.want)
|
||||
be.Equal(t, cmd, test.want)
|
||||
}
|
||||
})
|
||||
}
|
||||
@@ -57,56 +57,52 @@ func TestSRemParse(t *testing.T) {
|
||||
|
||||
func TestSRemExec(t *testing.T) {
|
||||
t.Run("some", func(t *testing.T) {
|
||||
db, red := getDB(t)
|
||||
defer db.Close()
|
||||
_, _ = db.Set().Add("key", "one", "two", "thr")
|
||||
red := getRedka(t)
|
||||
_, _ = red.Set().Add("key", "one", "two", "thr")
|
||||
|
||||
cmd := redis.MustParse(ParseSRem, "srem key one thr")
|
||||
conn := redis.NewFakeConn()
|
||||
res, err := cmd.Run(conn, red)
|
||||
testx.AssertNoErr(t, err)
|
||||
testx.AssertEqual(t, res, 2)
|
||||
testx.AssertEqual(t, conn.Out(), "2")
|
||||
be.Err(t, err, nil)
|
||||
be.Equal(t, res, 2)
|
||||
be.Equal(t, conn.Out(), "2")
|
||||
|
||||
items, _ := db.Set().Items("key")
|
||||
testx.AssertEqual(t, items, []core.Value{core.Value("two")})
|
||||
items, _ := red.Set().Items("key")
|
||||
be.Equal(t, items, []core.Value{core.Value("two")})
|
||||
})
|
||||
t.Run("none", func(t *testing.T) {
|
||||
db, red := getDB(t)
|
||||
defer db.Close()
|
||||
_, _ = db.Set().Add("key", "one", "two", "thr")
|
||||
red := getRedka(t)
|
||||
_, _ = red.Set().Add("key", "one", "two", "thr")
|
||||
|
||||
cmd := redis.MustParse(ParseSRem, "srem key fou fiv")
|
||||
conn := redis.NewFakeConn()
|
||||
res, err := cmd.Run(conn, red)
|
||||
testx.AssertNoErr(t, err)
|
||||
testx.AssertEqual(t, res, 0)
|
||||
testx.AssertEqual(t, conn.Out(), "0")
|
||||
be.Err(t, err, nil)
|
||||
be.Equal(t, res, 0)
|
||||
be.Equal(t, conn.Out(), "0")
|
||||
|
||||
slen, _ := db.Set().Len("key")
|
||||
testx.AssertEqual(t, slen, 3)
|
||||
slen, _ := red.Set().Len("key")
|
||||
be.Equal(t, slen, 3)
|
||||
})
|
||||
t.Run("key not found", func(t *testing.T) {
|
||||
db, red := getDB(t)
|
||||
defer db.Close()
|
||||
red := getRedka(t)
|
||||
|
||||
cmd := redis.MustParse(ParseSRem, "srem key one two")
|
||||
conn := redis.NewFakeConn()
|
||||
res, err := cmd.Run(conn, red)
|
||||
testx.AssertNoErr(t, err)
|
||||
testx.AssertEqual(t, res, 0)
|
||||
testx.AssertEqual(t, conn.Out(), "0")
|
||||
be.Err(t, err, nil)
|
||||
be.Equal(t, res, 0)
|
||||
be.Equal(t, conn.Out(), "0")
|
||||
})
|
||||
t.Run("key type mismatch", func(t *testing.T) {
|
||||
db, red := getDB(t)
|
||||
defer db.Close()
|
||||
_ = db.Str().Set("key", "str")
|
||||
red := getRedka(t)
|
||||
_ = red.Str().Set("key", "str")
|
||||
|
||||
cmd := redis.MustParse(ParseSRem, "srem key one two")
|
||||
conn := redis.NewFakeConn()
|
||||
res, err := cmd.Run(conn, red)
|
||||
testx.AssertNoErr(t, err)
|
||||
testx.AssertEqual(t, res, 0)
|
||||
testx.AssertEqual(t, conn.Out(), "0")
|
||||
be.Err(t, err, nil)
|
||||
be.Equal(t, res, 0)
|
||||
be.Equal(t, conn.Out(), "0")
|
||||
})
|
||||
}
|
||||
|
||||
@@ -1,12 +1,13 @@
|
||||
package set
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"testing"
|
||||
|
||||
"github.com/nalgeon/be"
|
||||
"github.com/nalgeon/redka/internal/core"
|
||||
"github.com/nalgeon/redka/internal/redis"
|
||||
"github.com/nalgeon/redka/internal/rset"
|
||||
"github.com/nalgeon/redka/internal/testx"
|
||||
)
|
||||
|
||||
func TestSScanParse(t *testing.T) {
|
||||
@@ -103,50 +104,53 @@ func TestSScanParse(t *testing.T) {
|
||||
for _, test := range tests {
|
||||
t.Run(test.cmd, func(t *testing.T) {
|
||||
cmd, err := redis.Parse(ParseSScan, test.cmd)
|
||||
testx.AssertEqual(t, err, test.err)
|
||||
be.Equal(t, err, test.err)
|
||||
if err == nil {
|
||||
testx.AssertEqual(t, cmd.key, test.key)
|
||||
testx.AssertEqual(t, cmd.cursor, test.cursor)
|
||||
testx.AssertEqual(t, cmd.match, test.match)
|
||||
testx.AssertEqual(t, cmd.count, test.count)
|
||||
be.Equal(t, cmd.key, test.key)
|
||||
be.Equal(t, cmd.cursor, test.cursor)
|
||||
be.Equal(t, cmd.match, test.match)
|
||||
be.Equal(t, cmd.count, test.count)
|
||||
} else {
|
||||
testx.AssertEqual(t, cmd, SScan{})
|
||||
be.Equal(t, cmd, SScan{})
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestSScanExec(t *testing.T) {
|
||||
db, red := getDB(t)
|
||||
defer db.Close()
|
||||
_, _ = db.Set().Add("key", "m11", "m12", "m21", "m22", "m31")
|
||||
red := getRedka(t)
|
||||
_, _ = red.Set().Add("key", "m11", "m12", "m21", "m22", "m31")
|
||||
|
||||
t.Run("sscan all", func(t *testing.T) {
|
||||
var cursor int
|
||||
{
|
||||
cmd := redis.MustParse(ParseSScan, "sscan key 0")
|
||||
conn := redis.NewFakeConn()
|
||||
|
||||
res, err := cmd.Run(conn, red)
|
||||
testx.AssertNoErr(t, err)
|
||||
be.Err(t, err, nil)
|
||||
|
||||
sres := res.(rset.ScanResult)
|
||||
testx.AssertEqual(t, sres.Cursor, 5)
|
||||
testx.AssertEqual(t, len(sres.Items), 5)
|
||||
testx.AssertEqual(t, sres.Items[0], core.Value("m11"))
|
||||
testx.AssertEqual(t, sres.Items[4], core.Value("m31"))
|
||||
testx.AssertEqual(t, conn.Out(), "2,5,5,m11,m12,m21,m22,m31")
|
||||
be.True(t, sres.Cursor > 0)
|
||||
be.Equal(t, len(sres.Items), 5)
|
||||
be.Equal(t, sres.Items[0], core.Value("m11"))
|
||||
be.Equal(t, sres.Items[4], core.Value("m31"))
|
||||
wantOut := fmt.Sprintf("2,%d,5,m11,m12,m21,m22,m31", sres.Cursor)
|
||||
be.Equal(t, conn.Out(), wantOut)
|
||||
cursor = sres.Cursor
|
||||
}
|
||||
{
|
||||
cmd := redis.MustParse(ParseSScan, "sscan key 5")
|
||||
next := fmt.Sprintf("sscan key %d", cursor)
|
||||
cmd := redis.MustParse(ParseSScan, next)
|
||||
conn := redis.NewFakeConn()
|
||||
|
||||
res, err := cmd.Run(conn, red)
|
||||
testx.AssertNoErr(t, err)
|
||||
be.Err(t, err, nil)
|
||||
|
||||
sres := res.(rset.ScanResult)
|
||||
testx.AssertEqual(t, sres.Cursor, 0)
|
||||
testx.AssertEqual(t, len(sres.Items), 0)
|
||||
testx.AssertEqual(t, conn.Out(), "2,0,0")
|
||||
be.Equal(t, sres.Cursor, 0)
|
||||
be.Equal(t, len(sres.Items), 0)
|
||||
be.Equal(t, conn.Out(), "2,0,0")
|
||||
}
|
||||
})
|
||||
t.Run("sscan pattern", func(t *testing.T) {
|
||||
@@ -154,72 +158,83 @@ func TestSScanExec(t *testing.T) {
|
||||
conn := redis.NewFakeConn()
|
||||
|
||||
res, err := cmd.Run(conn, red)
|
||||
testx.AssertNoErr(t, err)
|
||||
be.Err(t, err, nil)
|
||||
|
||||
sres := res.(rset.ScanResult)
|
||||
testx.AssertEqual(t, sres.Cursor, 4)
|
||||
testx.AssertEqual(t, len(sres.Items), 2)
|
||||
testx.AssertEqual(t, sres.Items[0].String(), "m21")
|
||||
testx.AssertEqual(t, sres.Items[1].String(), "m22")
|
||||
testx.AssertEqual(t, conn.Out(), "2,4,2,m21,m22")
|
||||
be.True(t, sres.Cursor > 0)
|
||||
be.Equal(t, len(sres.Items), 2)
|
||||
be.Equal(t, sres.Items[0].String(), "m21")
|
||||
be.Equal(t, sres.Items[1].String(), "m22")
|
||||
wantOut := fmt.Sprintf("2,%d,2,m21,m22", sres.Cursor)
|
||||
be.Equal(t, conn.Out(), wantOut)
|
||||
})
|
||||
t.Run("sscan count", func(t *testing.T) {
|
||||
var cursor int
|
||||
{
|
||||
// page 1
|
||||
cmd := redis.MustParse(ParseSScan, "sscan key 0 match * count 2")
|
||||
conn := redis.NewFakeConn()
|
||||
|
||||
res, err := cmd.Run(conn, red)
|
||||
testx.AssertNoErr(t, err)
|
||||
be.Err(t, err, nil)
|
||||
|
||||
sres := res.(rset.ScanResult)
|
||||
testx.AssertEqual(t, sres.Cursor, 2)
|
||||
testx.AssertEqual(t, len(sres.Items), 2)
|
||||
testx.AssertEqual(t, sres.Items[0].String(), "m11")
|
||||
testx.AssertEqual(t, sres.Items[1].String(), "m12")
|
||||
testx.AssertEqual(t, conn.Out(), "2,2,2,m11,m12")
|
||||
be.True(t, sres.Cursor > 0)
|
||||
be.Equal(t, len(sres.Items), 2)
|
||||
be.Equal(t, sres.Items[0].String(), "m11")
|
||||
be.Equal(t, sres.Items[1].String(), "m12")
|
||||
wantOut := fmt.Sprintf("2,%d,2,m11,m12", sres.Cursor)
|
||||
be.Equal(t, conn.Out(), wantOut)
|
||||
cursor = sres.Cursor
|
||||
}
|
||||
{
|
||||
// page 2
|
||||
cmd := redis.MustParse(ParseSScan, "sscan key 2 match * count 2")
|
||||
next := fmt.Sprintf("sscan key %d match * count 2", cursor)
|
||||
cmd := redis.MustParse(ParseSScan, next)
|
||||
conn := redis.NewFakeConn()
|
||||
|
||||
res, err := cmd.Run(conn, red)
|
||||
testx.AssertNoErr(t, err)
|
||||
be.Err(t, err, nil)
|
||||
|
||||
sres := res.(rset.ScanResult)
|
||||
testx.AssertEqual(t, sres.Cursor, 4)
|
||||
testx.AssertEqual(t, len(sres.Items), 2)
|
||||
testx.AssertEqual(t, sres.Items[0].String(), "m21")
|
||||
testx.AssertEqual(t, sres.Items[1].String(), "m22")
|
||||
testx.AssertEqual(t, conn.Out(), "2,4,2,m21,m22")
|
||||
be.True(t, sres.Cursor > cursor)
|
||||
be.Equal(t, len(sres.Items), 2)
|
||||
be.Equal(t, sres.Items[0].String(), "m21")
|
||||
be.Equal(t, sres.Items[1].String(), "m22")
|
||||
wantOut := fmt.Sprintf("2,%d,2,m21,m22", sres.Cursor)
|
||||
be.Equal(t, conn.Out(), wantOut)
|
||||
cursor = sres.Cursor
|
||||
}
|
||||
{
|
||||
// page 3
|
||||
cmd := redis.MustParse(ParseSScan, "sscan key 4 match * count 2")
|
||||
next := fmt.Sprintf("sscan key %d match * count 2", cursor)
|
||||
cmd := redis.MustParse(ParseSScan, next)
|
||||
conn := redis.NewFakeConn()
|
||||
|
||||
res, err := cmd.Run(conn, red)
|
||||
testx.AssertNoErr(t, err)
|
||||
be.Err(t, err, nil)
|
||||
|
||||
sres := res.(rset.ScanResult)
|
||||
testx.AssertEqual(t, sres.Cursor, 5)
|
||||
testx.AssertEqual(t, len(sres.Items), 1)
|
||||
testx.AssertEqual(t, sres.Items[0].String(), "m31")
|
||||
testx.AssertEqual(t, conn.Out(), "2,5,1,m31")
|
||||
be.True(t, sres.Cursor > cursor)
|
||||
be.Equal(t, len(sres.Items), 1)
|
||||
be.Equal(t, sres.Items[0].String(), "m31")
|
||||
wantOut := fmt.Sprintf("2,%d,1,m31", sres.Cursor)
|
||||
be.Equal(t, conn.Out(), wantOut)
|
||||
cursor = sres.Cursor
|
||||
}
|
||||
{
|
||||
// no more pages
|
||||
cmd := redis.MustParse(ParseSScan, "sscan key 5 match * count 2")
|
||||
next := fmt.Sprintf("sscan key %d match * count 2", cursor)
|
||||
cmd := redis.MustParse(ParseSScan, next)
|
||||
conn := redis.NewFakeConn()
|
||||
|
||||
res, err := cmd.Run(conn, red)
|
||||
testx.AssertNoErr(t, err)
|
||||
be.Err(t, err, nil)
|
||||
|
||||
sres := res.(rset.ScanResult)
|
||||
testx.AssertEqual(t, sres.Cursor, 0)
|
||||
testx.AssertEqual(t, len(sres.Items), 0)
|
||||
testx.AssertEqual(t, conn.Out(), "2,0,0")
|
||||
be.Equal(t, sres.Cursor, 0)
|
||||
be.Equal(t, len(sres.Items), 0)
|
||||
be.Equal(t, conn.Out(), "2,0,0")
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
@@ -3,9 +3,9 @@ package set
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/nalgeon/be"
|
||||
"github.com/nalgeon/redka/internal/core"
|
||||
"github.com/nalgeon/redka/internal/redis"
|
||||
"github.com/nalgeon/redka/internal/testx"
|
||||
)
|
||||
|
||||
func TestSUnionParse(t *testing.T) {
|
||||
@@ -34,11 +34,11 @@ func TestSUnionParse(t *testing.T) {
|
||||
for _, test := range tests {
|
||||
t.Run(test.cmd, func(t *testing.T) {
|
||||
cmd, err := redis.Parse(ParseSUnion, test.cmd)
|
||||
testx.AssertEqual(t, err, test.err)
|
||||
be.Equal(t, err, test.err)
|
||||
if err == nil {
|
||||
testx.AssertEqual(t, cmd.keys, test.want.keys)
|
||||
be.Equal(t, cmd.keys, test.want.keys)
|
||||
} else {
|
||||
testx.AssertEqual(t, cmd, test.want)
|
||||
be.Equal(t, cmd, test.want)
|
||||
}
|
||||
})
|
||||
}
|
||||
@@ -46,78 +46,72 @@ func TestSUnionParse(t *testing.T) {
|
||||
|
||||
func TestSUnionExec(t *testing.T) {
|
||||
t.Run("non-empty", func(t *testing.T) {
|
||||
db, red := getDB(t)
|
||||
defer db.Close()
|
||||
_, _ = db.Set().Add("key1", "one", "two")
|
||||
_, _ = db.Set().Add("key2", "two", "thr")
|
||||
_, _ = db.Set().Add("key3", "thr", "fou")
|
||||
red := getRedka(t)
|
||||
_, _ = red.Set().Add("key1", "one", "two")
|
||||
_, _ = red.Set().Add("key2", "two", "thr")
|
||||
_, _ = red.Set().Add("key3", "thr", "fou")
|
||||
|
||||
cmd := redis.MustParse(ParseSUnion, "sunion key1 key2 key3")
|
||||
conn := redis.NewFakeConn()
|
||||
res, err := cmd.Run(conn, red)
|
||||
testx.AssertNoErr(t, err)
|
||||
testx.AssertEqual(t, len(res.([]core.Value)), 4)
|
||||
testx.AssertEqual(t, conn.Out(), "4,fou,one,thr,two")
|
||||
be.Err(t, err, nil)
|
||||
be.Equal(t, len(res.([]core.Value)), 4)
|
||||
be.Equal(t, conn.Out(), "4,fou,one,thr,two")
|
||||
})
|
||||
t.Run("no keys", func(t *testing.T) {
|
||||
db, red := getDB(t)
|
||||
defer db.Close()
|
||||
red := getRedka(t)
|
||||
|
||||
cmd := redis.MustParse(ParseSUnion, "sunion key1")
|
||||
conn := redis.NewFakeConn()
|
||||
res, err := cmd.Run(conn, red)
|
||||
testx.AssertNoErr(t, err)
|
||||
testx.AssertEqual(t, len(res.([]core.Value)), 0)
|
||||
testx.AssertEqual(t, conn.Out(), "0")
|
||||
be.Err(t, err, nil)
|
||||
be.Equal(t, len(res.([]core.Value)), 0)
|
||||
be.Equal(t, conn.Out(), "0")
|
||||
})
|
||||
t.Run("single key", func(t *testing.T) {
|
||||
db, red := getDB(t)
|
||||
defer db.Close()
|
||||
_, _ = db.Set().Add("key1", "one", "two", "thr")
|
||||
red := getRedka(t)
|
||||
_, _ = red.Set().Add("key1", "one", "two", "thr")
|
||||
|
||||
cmd := redis.MustParse(ParseSUnion, "sunion key1")
|
||||
conn := redis.NewFakeConn()
|
||||
res, err := cmd.Run(conn, red)
|
||||
testx.AssertNoErr(t, err)
|
||||
testx.AssertEqual(t, len(res.([]core.Value)), 3)
|
||||
testx.AssertEqual(t, conn.Out(), "3,one,thr,two")
|
||||
be.Err(t, err, nil)
|
||||
be.Equal(t, len(res.([]core.Value)), 3)
|
||||
be.Equal(t, conn.Out(), "3,one,thr,two")
|
||||
})
|
||||
t.Run("key not found", func(t *testing.T) {
|
||||
db, red := getDB(t)
|
||||
defer db.Close()
|
||||
_, _ = db.Set().Add("key1", "one")
|
||||
_, _ = db.Set().Add("key2", "two")
|
||||
red := getRedka(t)
|
||||
_, _ = red.Set().Add("key1", "one")
|
||||
_, _ = red.Set().Add("key2", "two")
|
||||
|
||||
cmd := redis.MustParse(ParseSUnion, "sunion key1 key2 key3")
|
||||
conn := redis.NewFakeConn()
|
||||
res, err := cmd.Run(conn, red)
|
||||
testx.AssertNoErr(t, err)
|
||||
testx.AssertEqual(t, len(res.([]core.Value)), 2)
|
||||
testx.AssertEqual(t, conn.Out(), "2,one,two")
|
||||
be.Err(t, err, nil)
|
||||
be.Equal(t, len(res.([]core.Value)), 2)
|
||||
be.Equal(t, conn.Out(), "2,one,two")
|
||||
})
|
||||
t.Run("all not found", func(t *testing.T) {
|
||||
db, red := getDB(t)
|
||||
defer db.Close()
|
||||
red := getRedka(t)
|
||||
|
||||
cmd := redis.MustParse(ParseSUnion, "sunion key1 key2 key3")
|
||||
conn := redis.NewFakeConn()
|
||||
res, err := cmd.Run(conn, red)
|
||||
testx.AssertNoErr(t, err)
|
||||
testx.AssertEqual(t, len(res.([]core.Value)), 0)
|
||||
testx.AssertEqual(t, conn.Out(), "0")
|
||||
be.Err(t, err, nil)
|
||||
be.Equal(t, len(res.([]core.Value)), 0)
|
||||
be.Equal(t, conn.Out(), "0")
|
||||
})
|
||||
t.Run("key type mismatch", func(t *testing.T) {
|
||||
db, red := getDB(t)
|
||||
defer db.Close()
|
||||
_, _ = db.Set().Add("key1", "one")
|
||||
_ = db.Str().Set("key2", "two")
|
||||
_, _ = db.Set().Add("key3", "thr")
|
||||
red := getRedka(t)
|
||||
_, _ = red.Set().Add("key1", "one")
|
||||
_ = red.Str().Set("key2", "two")
|
||||
_, _ = red.Set().Add("key3", "thr")
|
||||
|
||||
cmd := redis.MustParse(ParseSUnion, "sunion key1 key2 key3")
|
||||
conn := redis.NewFakeConn()
|
||||
res, err := cmd.Run(conn, red)
|
||||
testx.AssertNoErr(t, err)
|
||||
testx.AssertEqual(t, len(res.([]core.Value)), 2)
|
||||
testx.AssertEqual(t, conn.Out(), "2,one,thr")
|
||||
be.Err(t, err, nil)
|
||||
be.Equal(t, len(res.([]core.Value)), 2)
|
||||
be.Equal(t, conn.Out(), "2,one,thr")
|
||||
})
|
||||
}
|
||||
|
||||
@@ -3,9 +3,9 @@ package set
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/nalgeon/be"
|
||||
"github.com/nalgeon/redka/internal/core"
|
||||
"github.com/nalgeon/redka/internal/redis"
|
||||
"github.com/nalgeon/redka/internal/testx"
|
||||
)
|
||||
|
||||
func TestSUnionStoreParse(t *testing.T) {
|
||||
@@ -39,12 +39,12 @@ func TestSUnionStoreParse(t *testing.T) {
|
||||
for _, test := range tests {
|
||||
t.Run(test.cmd, func(t *testing.T) {
|
||||
cmd, err := redis.Parse(ParseSUnionStore, test.cmd)
|
||||
testx.AssertEqual(t, err, test.err)
|
||||
be.Equal(t, err, test.err)
|
||||
if err == nil {
|
||||
testx.AssertEqual(t, cmd.dest, test.want.dest)
|
||||
testx.AssertEqual(t, cmd.keys, test.want.keys)
|
||||
be.Equal(t, cmd.dest, test.want.dest)
|
||||
be.Equal(t, cmd.keys, test.want.keys)
|
||||
} else {
|
||||
testx.AssertEqual(t, cmd, test.want)
|
||||
be.Equal(t, cmd, test.want)
|
||||
}
|
||||
})
|
||||
}
|
||||
@@ -52,123 +52,116 @@ func TestSUnionStoreParse(t *testing.T) {
|
||||
|
||||
func TestSUnionStoreExec(t *testing.T) {
|
||||
t.Run("store", func(t *testing.T) {
|
||||
db, red := getDB(t)
|
||||
defer db.Close()
|
||||
_, _ = db.Set().Add("key1", "one", "two", "thr")
|
||||
_, _ = db.Set().Add("key2", "two", "thr", "fou")
|
||||
_, _ = db.Set().Add("key3", "one", "two", "thr", "fou")
|
||||
red := getRedka(t)
|
||||
_, _ = red.Set().Add("key1", "one", "two", "thr")
|
||||
_, _ = red.Set().Add("key2", "two", "thr", "fou")
|
||||
_, _ = red.Set().Add("key3", "one", "two", "thr", "fou")
|
||||
|
||||
cmd := redis.MustParse(ParseSUnionStore, "sunionstore dest key1 key2 key3")
|
||||
conn := redis.NewFakeConn()
|
||||
res, err := cmd.Run(conn, red)
|
||||
testx.AssertNoErr(t, err)
|
||||
testx.AssertEqual(t, res, 4)
|
||||
testx.AssertEqual(t, conn.Out(), "4")
|
||||
be.Err(t, err, nil)
|
||||
be.Equal(t, res, 4)
|
||||
be.Equal(t, conn.Out(), "4")
|
||||
|
||||
items, _ := db.Set().Items("dest")
|
||||
items, _ := red.Set().Items("dest")
|
||||
sortValues(items)
|
||||
testx.AssertEqual(t, items, []core.Value{
|
||||
be.Equal(t, items, []core.Value{
|
||||
core.Value("fou"), core.Value("one"), core.Value("thr"), core.Value("two"),
|
||||
})
|
||||
})
|
||||
t.Run("rewrite dest", func(t *testing.T) {
|
||||
db, red := getDB(t)
|
||||
defer db.Close()
|
||||
_, _ = db.Set().Add("key1", "one")
|
||||
_, _ = db.Set().Add("key2", "one")
|
||||
_, _ = db.Set().Add("dest", "old")
|
||||
red := getRedka(t)
|
||||
_, _ = red.Set().Add("key1", "one")
|
||||
_, _ = red.Set().Add("key2", "one")
|
||||
_, _ = red.Set().Add("dest", "old")
|
||||
|
||||
cmd := redis.MustParse(ParseSUnionStore, "sunionstore dest key1 key2")
|
||||
conn := redis.NewFakeConn()
|
||||
res, err := cmd.Run(conn, red)
|
||||
testx.AssertNoErr(t, err)
|
||||
testx.AssertEqual(t, res, 1)
|
||||
testx.AssertEqual(t, conn.Out(), "1")
|
||||
be.Err(t, err, nil)
|
||||
be.Equal(t, res, 1)
|
||||
be.Equal(t, conn.Out(), "1")
|
||||
|
||||
items, _ := db.Set().Items("dest")
|
||||
testx.AssertEqual(t, items, []core.Value{core.Value("one")})
|
||||
items, _ := red.Set().Items("dest")
|
||||
be.Equal(t, items, []core.Value{core.Value("one")})
|
||||
})
|
||||
t.Run("single key", func(t *testing.T) {
|
||||
db, red := getDB(t)
|
||||
defer db.Close()
|
||||
_, _ = db.Set().Add("key1", "one", "two")
|
||||
_, _ = db.Set().Add("dest", "old")
|
||||
red := getRedka(t)
|
||||
_, _ = red.Set().Add("key1", "one", "two")
|
||||
_, _ = red.Set().Add("dest", "old")
|
||||
|
||||
cmd := redis.MustParse(ParseSUnionStore, "sunionstore dest key1")
|
||||
conn := redis.NewFakeConn()
|
||||
res, err := cmd.Run(conn, red)
|
||||
testx.AssertNoErr(t, err)
|
||||
testx.AssertEqual(t, res, 2)
|
||||
testx.AssertEqual(t, conn.Out(), "2")
|
||||
be.Err(t, err, nil)
|
||||
be.Equal(t, res, 2)
|
||||
be.Equal(t, conn.Out(), "2")
|
||||
|
||||
items, _ := db.Set().Items("dest")
|
||||
items, _ := red.Set().Items("dest")
|
||||
sortValues(items)
|
||||
testx.AssertEqual(t, items, []core.Value{core.Value("one"), core.Value("two")})
|
||||
be.Equal(t, items, []core.Value{core.Value("one"), core.Value("two")})
|
||||
})
|
||||
t.Run("empty", func(t *testing.T) {
|
||||
db, red := getDB(t)
|
||||
defer db.Close()
|
||||
_, _ = db.Set().Add("dest", "old")
|
||||
red := getRedka(t)
|
||||
_, _ = red.Set().Add("dest", "old")
|
||||
|
||||
cmd := redis.MustParse(ParseSUnionStore, "sunionstore dest key1 key2")
|
||||
conn := redis.NewFakeConn()
|
||||
res, err := cmd.Run(conn, red)
|
||||
testx.AssertNoErr(t, err)
|
||||
testx.AssertEqual(t, res, 0)
|
||||
testx.AssertEqual(t, conn.Out(), "0")
|
||||
be.Err(t, err, nil)
|
||||
be.Equal(t, res, 0)
|
||||
be.Equal(t, conn.Out(), "0")
|
||||
|
||||
items, _ := db.Set().Items("dest")
|
||||
testx.AssertEqual(t, items, []core.Value(nil))
|
||||
items, _ := red.Set().Items("dest")
|
||||
be.Equal(t, items, []core.Value(nil))
|
||||
})
|
||||
t.Run("source key not found", func(t *testing.T) {
|
||||
db, red := getDB(t)
|
||||
defer db.Close()
|
||||
_, _ = db.Set().Add("key1", "one")
|
||||
_, _ = db.Set().Add("key2", "one")
|
||||
_, _ = db.Set().Add("dest", "old")
|
||||
red := getRedka(t)
|
||||
_, _ = red.Set().Add("key1", "one")
|
||||
_, _ = red.Set().Add("key2", "one")
|
||||
_, _ = red.Set().Add("dest", "old")
|
||||
|
||||
cmd := redis.MustParse(ParseSUnionStore, "sunionstore dest key1 key2 key3")
|
||||
conn := redis.NewFakeConn()
|
||||
res, err := cmd.Run(conn, red)
|
||||
testx.AssertNoErr(t, err)
|
||||
testx.AssertEqual(t, res, 1)
|
||||
testx.AssertEqual(t, conn.Out(), "1")
|
||||
be.Err(t, err, nil)
|
||||
be.Equal(t, res, 1)
|
||||
be.Equal(t, conn.Out(), "1")
|
||||
|
||||
items, _ := db.Set().Items("dest")
|
||||
testx.AssertEqual(t, items, []core.Value{core.Value("one")})
|
||||
items, _ := red.Set().Items("dest")
|
||||
be.Equal(t, items, []core.Value{core.Value("one")})
|
||||
})
|
||||
t.Run("source key type mismatch", func(t *testing.T) {
|
||||
db, red := getDB(t)
|
||||
defer db.Close()
|
||||
_, _ = db.Set().Add("key1", "one")
|
||||
_, _ = db.Set().Add("key2", "one")
|
||||
_ = db.Str().Set("key3", "one")
|
||||
red := getRedka(t)
|
||||
_, _ = red.Set().Add("key1", "one")
|
||||
_, _ = red.Set().Add("key2", "one")
|
||||
_ = red.Str().Set("key3", "one")
|
||||
|
||||
cmd := redis.MustParse(ParseSUnionStore, "sunionstore dest key1 key2 key3")
|
||||
conn := redis.NewFakeConn()
|
||||
res, err := cmd.Run(conn, red)
|
||||
testx.AssertNoErr(t, err)
|
||||
testx.AssertEqual(t, res, 1)
|
||||
testx.AssertEqual(t, conn.Out(), "1")
|
||||
be.Err(t, err, nil)
|
||||
be.Equal(t, res, 1)
|
||||
be.Equal(t, conn.Out(), "1")
|
||||
|
||||
items, _ := db.Set().Items("dest")
|
||||
testx.AssertEqual(t, items, []core.Value{core.Value("one")})
|
||||
items, _ := red.Set().Items("dest")
|
||||
be.Equal(t, items, []core.Value{core.Value("one")})
|
||||
})
|
||||
t.Run("dest key type mismatch", func(t *testing.T) {
|
||||
db, red := getDB(t)
|
||||
defer db.Close()
|
||||
_, _ = db.Set().Add("key1", "one")
|
||||
_, _ = db.Set().Add("key2", "one")
|
||||
_ = db.Str().Set("dest", "old")
|
||||
red := getRedka(t)
|
||||
_, _ = red.Set().Add("key1", "one")
|
||||
_, _ = red.Set().Add("key2", "one")
|
||||
_ = red.Str().Set("dest", "old")
|
||||
|
||||
cmd := redis.MustParse(ParseSUnionStore, "sunionstore dest key1 key2")
|
||||
conn := redis.NewFakeConn()
|
||||
res, err := cmd.Run(conn, red)
|
||||
testx.AssertErr(t, err, core.ErrKeyType)
|
||||
testx.AssertEqual(t, res, nil)
|
||||
testx.AssertEqual(t, conn.Out(), core.ErrKeyType.Error()+" (sunionstore)")
|
||||
be.Err(t, err, core.ErrKeyType)
|
||||
be.Equal(t, res, nil)
|
||||
be.Equal(t, conn.Out(), core.ErrKeyType.Error()+" (sunionstore)")
|
||||
|
||||
sval, _ := db.Str().Get("dest")
|
||||
testx.AssertEqual(t, sval, core.Value("old"))
|
||||
sval, _ := red.Str().Get("dest")
|
||||
be.Equal(t, sval, core.Value("old"))
|
||||
})
|
||||
}
|
||||
|
||||
@@ -3,8 +3,8 @@ package string
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/nalgeon/be"
|
||||
"github.com/nalgeon/redka/internal/redis"
|
||||
"github.com/nalgeon/redka/internal/testx"
|
||||
)
|
||||
|
||||
func TestDecrParse(t *testing.T) {
|
||||
@@ -37,12 +37,12 @@ func TestDecrParse(t *testing.T) {
|
||||
for _, test := range tests {
|
||||
t.Run(test.cmd, func(t *testing.T) {
|
||||
cmd, err := redis.Parse(parse, test.cmd)
|
||||
testx.AssertEqual(t, err, test.err)
|
||||
be.Equal(t, err, test.err)
|
||||
if err == nil {
|
||||
testx.AssertEqual(t, cmd.key, test.want.key)
|
||||
testx.AssertEqual(t, cmd.delta, test.want.delta)
|
||||
be.Equal(t, cmd.key, test.want.key)
|
||||
be.Equal(t, cmd.delta, test.want.delta)
|
||||
} else {
|
||||
testx.AssertEqual(t, cmd, test.want)
|
||||
be.Equal(t, cmd, test.want)
|
||||
}
|
||||
})
|
||||
}
|
||||
@@ -54,33 +54,31 @@ func TestDecrExec(t *testing.T) {
|
||||
}
|
||||
|
||||
t.Run("create", func(t *testing.T) {
|
||||
db, red := getDB(t)
|
||||
defer db.Close()
|
||||
red := getRedka(t)
|
||||
|
||||
cmd := redis.MustParse(parse, "decr age")
|
||||
conn := redis.NewFakeConn()
|
||||
res, err := cmd.Run(conn, red)
|
||||
testx.AssertNoErr(t, err)
|
||||
testx.AssertEqual(t, res, -1)
|
||||
testx.AssertEqual(t, conn.Out(), "-1")
|
||||
be.Err(t, err, nil)
|
||||
be.Equal(t, res, -1)
|
||||
be.Equal(t, conn.Out(), "-1")
|
||||
|
||||
age, _ := db.Str().Get("age")
|
||||
testx.AssertEqual(t, age.MustInt(), -1)
|
||||
age, _ := red.Str().Get("age")
|
||||
be.Equal(t, age.MustInt(), -1)
|
||||
})
|
||||
|
||||
t.Run("decr", func(t *testing.T) {
|
||||
db, red := getDB(t)
|
||||
defer db.Close()
|
||||
_ = db.Str().Set("age", "25")
|
||||
red := getRedka(t)
|
||||
_ = red.Str().Set("age", "25")
|
||||
|
||||
cmd := redis.MustParse(parse, "decr age")
|
||||
conn := redis.NewFakeConn()
|
||||
res, err := cmd.Run(conn, red)
|
||||
testx.AssertNoErr(t, err)
|
||||
testx.AssertEqual(t, res, 24)
|
||||
testx.AssertEqual(t, conn.Out(), "24")
|
||||
be.Err(t, err, nil)
|
||||
be.Equal(t, res, 24)
|
||||
be.Equal(t, conn.Out(), "24")
|
||||
|
||||
age, _ := db.Str().Get("age")
|
||||
testx.AssertEqual(t, age.MustInt(), 24)
|
||||
age, _ := red.Str().Get("age")
|
||||
be.Equal(t, age.MustInt(), 24)
|
||||
})
|
||||
}
|
||||
|
||||
@@ -3,8 +3,8 @@ package string
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/nalgeon/be"
|
||||
"github.com/nalgeon/redka/internal/redis"
|
||||
"github.com/nalgeon/redka/internal/testx"
|
||||
)
|
||||
|
||||
func TestDecrByParse(t *testing.T) {
|
||||
@@ -37,12 +37,12 @@ func TestDecrByParse(t *testing.T) {
|
||||
for _, test := range tests {
|
||||
t.Run(test.cmd, func(t *testing.T) {
|
||||
cmd, err := redis.Parse(parse, test.cmd)
|
||||
testx.AssertEqual(t, err, test.err)
|
||||
be.Equal(t, err, test.err)
|
||||
if err == nil {
|
||||
testx.AssertEqual(t, cmd.key, test.want.key)
|
||||
testx.AssertEqual(t, cmd.delta, test.want.delta)
|
||||
be.Equal(t, cmd.key, test.want.key)
|
||||
be.Equal(t, cmd.delta, test.want.delta)
|
||||
} else {
|
||||
testx.AssertEqual(t, cmd, test.want)
|
||||
be.Equal(t, cmd, test.want)
|
||||
}
|
||||
})
|
||||
}
|
||||
@@ -54,33 +54,31 @@ func TestDecrByExec(t *testing.T) {
|
||||
}
|
||||
|
||||
t.Run("create", func(t *testing.T) {
|
||||
db, red := getDB(t)
|
||||
defer db.Close()
|
||||
red := getRedka(t)
|
||||
|
||||
cmd := redis.MustParse(parse, "decrby age 12")
|
||||
conn := redis.NewFakeConn()
|
||||
res, err := cmd.Run(conn, red)
|
||||
testx.AssertNoErr(t, err)
|
||||
testx.AssertEqual(t, res, -12)
|
||||
testx.AssertEqual(t, conn.Out(), "-12")
|
||||
be.Err(t, err, nil)
|
||||
be.Equal(t, res, -12)
|
||||
be.Equal(t, conn.Out(), "-12")
|
||||
|
||||
age, _ := db.Str().Get("age")
|
||||
testx.AssertEqual(t, age.MustInt(), -12)
|
||||
age, _ := red.Str().Get("age")
|
||||
be.Equal(t, age.MustInt(), -12)
|
||||
})
|
||||
|
||||
t.Run("decrby", func(t *testing.T) {
|
||||
db, red := getDB(t)
|
||||
defer db.Close()
|
||||
_ = db.Str().Set("age", "25")
|
||||
red := getRedka(t)
|
||||
_ = red.Str().Set("age", "25")
|
||||
|
||||
cmd := redis.MustParse(parse, "decrby age 12")
|
||||
conn := redis.NewFakeConn()
|
||||
res, err := cmd.Run(conn, red)
|
||||
testx.AssertNoErr(t, err)
|
||||
testx.AssertEqual(t, res, 13)
|
||||
testx.AssertEqual(t, conn.Out(), "13")
|
||||
be.Err(t, err, nil)
|
||||
be.Equal(t, res, 13)
|
||||
be.Equal(t, conn.Out(), "13")
|
||||
|
||||
age, _ := db.Str().Get("age")
|
||||
testx.AssertEqual(t, age.MustInt(), 13)
|
||||
age, _ := red.Str().Get("age")
|
||||
be.Equal(t, age.MustInt(), 13)
|
||||
})
|
||||
}
|
||||
|
||||
@@ -3,9 +3,9 @@ package string
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/nalgeon/be"
|
||||
"github.com/nalgeon/redka/internal/core"
|
||||
"github.com/nalgeon/redka/internal/redis"
|
||||
"github.com/nalgeon/redka/internal/testx"
|
||||
)
|
||||
|
||||
func TestGetParse(t *testing.T) {
|
||||
@@ -34,21 +34,19 @@ func TestGetParse(t *testing.T) {
|
||||
for _, test := range tests {
|
||||
t.Run(test.cmd, func(t *testing.T) {
|
||||
cmd, err := redis.Parse(ParseGet, test.cmd)
|
||||
testx.AssertEqual(t, err, test.err)
|
||||
be.Equal(t, err, test.err)
|
||||
if err == nil {
|
||||
testx.AssertEqual(t, cmd.key, test.want)
|
||||
be.Equal(t, cmd.key, test.want)
|
||||
} else {
|
||||
testx.AssertEqual(t, cmd, Get{})
|
||||
be.Equal(t, cmd, Get{})
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestGetExec(t *testing.T) {
|
||||
db, red := getDB(t)
|
||||
defer db.Close()
|
||||
|
||||
_ = db.Str().Set("name", "alice")
|
||||
red := getRedka(t)
|
||||
_ = red.Str().Set("name", "alice")
|
||||
|
||||
tests := []struct {
|
||||
cmd string
|
||||
@@ -72,9 +70,9 @@ func TestGetExec(t *testing.T) {
|
||||
conn := redis.NewFakeConn()
|
||||
cmd := redis.MustParse(ParseGet, test.cmd)
|
||||
res, err := cmd.Run(conn, red)
|
||||
testx.AssertNoErr(t, err)
|
||||
testx.AssertEqual(t, res, test.res)
|
||||
testx.AssertEqual(t, conn.Out(), test.out)
|
||||
be.Err(t, err, nil)
|
||||
be.Equal(t, res, test.res)
|
||||
be.Equal(t, conn.Out(), test.out)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3,9 +3,9 @@ package string
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/nalgeon/be"
|
||||
"github.com/nalgeon/redka/internal/core"
|
||||
"github.com/nalgeon/redka/internal/redis"
|
||||
"github.com/nalgeon/redka/internal/testx"
|
||||
)
|
||||
|
||||
func TestGetSetParse(t *testing.T) {
|
||||
@@ -39,12 +39,12 @@ func TestGetSetParse(t *testing.T) {
|
||||
for _, test := range tests {
|
||||
t.Run(test.cmd, func(t *testing.T) {
|
||||
cmd, err := redis.Parse(ParseGetSet, test.cmd)
|
||||
testx.AssertEqual(t, err, test.err)
|
||||
be.Equal(t, err, test.err)
|
||||
if err == nil {
|
||||
testx.AssertEqual(t, cmd.key, test.want.key)
|
||||
testx.AssertEqual(t, cmd.value, test.want.value)
|
||||
be.Equal(t, cmd.key, test.want.key)
|
||||
be.Equal(t, cmd.value, test.want.value)
|
||||
} else {
|
||||
testx.AssertEqual(t, cmd, test.want)
|
||||
be.Equal(t, cmd, test.want)
|
||||
}
|
||||
})
|
||||
}
|
||||
@@ -52,34 +52,31 @@ func TestGetSetParse(t *testing.T) {
|
||||
|
||||
func TestGetSetExec(t *testing.T) {
|
||||
t.Run("create", func(t *testing.T) {
|
||||
db, red := getDB(t)
|
||||
defer db.Close()
|
||||
red := getRedka(t)
|
||||
|
||||
cmd := redis.MustParse(ParseGetSet, "getset name alice")
|
||||
conn := redis.NewFakeConn()
|
||||
res, err := cmd.Run(conn, red)
|
||||
testx.AssertNoErr(t, err)
|
||||
testx.AssertEqual(t, res, core.Value(nil))
|
||||
testx.AssertEqual(t, conn.Out(), "(nil)")
|
||||
be.Err(t, err, nil)
|
||||
be.Equal(t, res.(core.Value), core.Value(nil))
|
||||
be.Equal(t, conn.Out(), "(nil)")
|
||||
|
||||
name, _ := db.Str().Get("name")
|
||||
testx.AssertEqual(t, name.String(), "alice")
|
||||
name, _ := red.Str().Get("name")
|
||||
be.Equal(t, name.String(), "alice")
|
||||
})
|
||||
|
||||
t.Run("update", func(t *testing.T) {
|
||||
db, red := getDB(t)
|
||||
defer db.Close()
|
||||
|
||||
_ = db.Str().Set("name", "alice")
|
||||
red := getRedka(t)
|
||||
_ = red.Str().Set("name", "alice")
|
||||
|
||||
cmd := redis.MustParse(ParseGetSet, "getset name bob")
|
||||
conn := redis.NewFakeConn()
|
||||
res, err := cmd.Run(conn, red)
|
||||
testx.AssertNoErr(t, err)
|
||||
testx.AssertEqual(t, res, core.Value("alice"))
|
||||
testx.AssertEqual(t, conn.Out(), "alice")
|
||||
be.Err(t, err, nil)
|
||||
be.Equal(t, res.(core.Value), core.Value("alice"))
|
||||
be.Equal(t, conn.Out(), "alice")
|
||||
|
||||
name, _ := db.Str().Get("name")
|
||||
testx.AssertEqual(t, name.String(), "bob")
|
||||
name, _ := red.Str().Get("name")
|
||||
be.Equal(t, name.String(), "bob")
|
||||
})
|
||||
}
|
||||
|
||||
@@ -3,8 +3,8 @@ package string
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/nalgeon/be"
|
||||
"github.com/nalgeon/redka/internal/redis"
|
||||
"github.com/nalgeon/redka/internal/testx"
|
||||
)
|
||||
|
||||
func TestIncrParse(t *testing.T) {
|
||||
@@ -37,12 +37,12 @@ func TestIncrParse(t *testing.T) {
|
||||
for _, test := range tests {
|
||||
t.Run(test.cmd, func(t *testing.T) {
|
||||
cmd, err := redis.Parse(parse, test.cmd)
|
||||
testx.AssertEqual(t, err, test.err)
|
||||
be.Equal(t, err, test.err)
|
||||
if err == nil {
|
||||
testx.AssertEqual(t, cmd.key, test.want.key)
|
||||
testx.AssertEqual(t, cmd.delta, test.want.delta)
|
||||
be.Equal(t, cmd.key, test.want.key)
|
||||
be.Equal(t, cmd.delta, test.want.delta)
|
||||
} else {
|
||||
testx.AssertEqual(t, cmd, test.want)
|
||||
be.Equal(t, cmd, test.want)
|
||||
}
|
||||
})
|
||||
}
|
||||
@@ -54,33 +54,31 @@ func TestIncrExec(t *testing.T) {
|
||||
}
|
||||
|
||||
t.Run("create", func(t *testing.T) {
|
||||
db, red := getDB(t)
|
||||
defer db.Close()
|
||||
red := getRedka(t)
|
||||
|
||||
cmd := redis.MustParse(parse, "incr age")
|
||||
conn := redis.NewFakeConn()
|
||||
res, err := cmd.Run(conn, red)
|
||||
testx.AssertNoErr(t, err)
|
||||
testx.AssertEqual(t, res, 1)
|
||||
testx.AssertEqual(t, conn.Out(), "1")
|
||||
be.Err(t, err, nil)
|
||||
be.Equal(t, res, 1)
|
||||
be.Equal(t, conn.Out(), "1")
|
||||
|
||||
age, _ := db.Str().Get("age")
|
||||
testx.AssertEqual(t, age.MustInt(), 1)
|
||||
age, _ := red.Str().Get("age")
|
||||
be.Equal(t, age.MustInt(), 1)
|
||||
})
|
||||
|
||||
t.Run("incr", func(t *testing.T) {
|
||||
db, red := getDB(t)
|
||||
defer db.Close()
|
||||
_ = db.Str().Set("age", "25")
|
||||
red := getRedka(t)
|
||||
_ = red.Str().Set("age", "25")
|
||||
|
||||
cmd := redis.MustParse(parse, "incr age")
|
||||
conn := redis.NewFakeConn()
|
||||
res, err := cmd.Run(conn, red)
|
||||
testx.AssertNoErr(t, err)
|
||||
testx.AssertEqual(t, res, 26)
|
||||
testx.AssertEqual(t, conn.Out(), "26")
|
||||
be.Err(t, err, nil)
|
||||
be.Equal(t, res, 26)
|
||||
be.Equal(t, conn.Out(), "26")
|
||||
|
||||
age, _ := db.Str().Get("age")
|
||||
testx.AssertEqual(t, age.MustInt(), 26)
|
||||
age, _ := red.Str().Get("age")
|
||||
be.Equal(t, age.MustInt(), 26)
|
||||
})
|
||||
}
|
||||
|
||||
@@ -3,8 +3,8 @@ package string
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/nalgeon/be"
|
||||
"github.com/nalgeon/redka/internal/redis"
|
||||
"github.com/nalgeon/redka/internal/testx"
|
||||
)
|
||||
|
||||
func TestIncrByParse(t *testing.T) {
|
||||
@@ -37,12 +37,12 @@ func TestIncrByParse(t *testing.T) {
|
||||
for _, test := range tests {
|
||||
t.Run(test.cmd, func(t *testing.T) {
|
||||
cmd, err := redis.Parse(parse, test.cmd)
|
||||
testx.AssertEqual(t, err, test.err)
|
||||
be.Equal(t, err, test.err)
|
||||
if err == nil {
|
||||
testx.AssertEqual(t, cmd.key, test.want.key)
|
||||
testx.AssertEqual(t, cmd.delta, test.want.delta)
|
||||
be.Equal(t, cmd.key, test.want.key)
|
||||
be.Equal(t, cmd.delta, test.want.delta)
|
||||
} else {
|
||||
testx.AssertEqual(t, cmd, test.want)
|
||||
be.Equal(t, cmd, test.want)
|
||||
}
|
||||
})
|
||||
}
|
||||
@@ -54,33 +54,31 @@ func TestIncrByExec(t *testing.T) {
|
||||
}
|
||||
|
||||
t.Run("create", func(t *testing.T) {
|
||||
db, red := getDB(t)
|
||||
defer db.Close()
|
||||
red := getRedka(t)
|
||||
|
||||
cmd := redis.MustParse(parse, "incrby age 42")
|
||||
conn := redis.NewFakeConn()
|
||||
res, err := cmd.Run(conn, red)
|
||||
testx.AssertNoErr(t, err)
|
||||
testx.AssertEqual(t, res, 42)
|
||||
testx.AssertEqual(t, conn.Out(), "42")
|
||||
be.Err(t, err, nil)
|
||||
be.Equal(t, res, 42)
|
||||
be.Equal(t, conn.Out(), "42")
|
||||
|
||||
age, _ := db.Str().Get("age")
|
||||
testx.AssertEqual(t, age.MustInt(), 42)
|
||||
age, _ := red.Str().Get("age")
|
||||
be.Equal(t, age.MustInt(), 42)
|
||||
})
|
||||
|
||||
t.Run("incrby", func(t *testing.T) {
|
||||
db, red := getDB(t)
|
||||
defer db.Close()
|
||||
_ = db.Str().Set("age", "25")
|
||||
red := getRedka(t)
|
||||
_ = red.Str().Set("age", "25")
|
||||
|
||||
cmd := redis.MustParse(parse, "incrby age 42")
|
||||
conn := redis.NewFakeConn()
|
||||
res, err := cmd.Run(conn, red)
|
||||
testx.AssertNoErr(t, err)
|
||||
testx.AssertEqual(t, res, 67)
|
||||
testx.AssertEqual(t, conn.Out(), "67")
|
||||
be.Err(t, err, nil)
|
||||
be.Equal(t, res, 67)
|
||||
be.Equal(t, conn.Out(), "67")
|
||||
|
||||
age, _ := db.Str().Get("age")
|
||||
testx.AssertEqual(t, age.MustInt(), 67)
|
||||
age, _ := red.Str().Get("age")
|
||||
be.Equal(t, age.MustInt(), 67)
|
||||
})
|
||||
}
|
||||
|
||||
@@ -3,8 +3,8 @@ package string
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/nalgeon/be"
|
||||
"github.com/nalgeon/redka/internal/redis"
|
||||
"github.com/nalgeon/redka/internal/testx"
|
||||
)
|
||||
|
||||
func TestIncrByFloatParse(t *testing.T) {
|
||||
@@ -43,20 +43,19 @@ func TestIncrByFloatParse(t *testing.T) {
|
||||
for _, test := range tests {
|
||||
t.Run(test.cmd, func(t *testing.T) {
|
||||
cmd, err := redis.Parse(ParseIncrByFloat, test.cmd)
|
||||
testx.AssertEqual(t, err, test.err)
|
||||
be.Equal(t, err, test.err)
|
||||
if err == nil {
|
||||
testx.AssertEqual(t, cmd.key, test.want.key)
|
||||
testx.AssertEqual(t, cmd.delta, test.want.delta)
|
||||
be.Equal(t, cmd.key, test.want.key)
|
||||
be.Equal(t, cmd.delta, test.want.delta)
|
||||
} else {
|
||||
testx.AssertEqual(t, cmd, test.want)
|
||||
be.Equal(t, cmd, test.want)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestIncrByFloatExec(t *testing.T) {
|
||||
db, red := getDB(t)
|
||||
defer db.Close()
|
||||
red := getRedka(t)
|
||||
|
||||
tests := []struct {
|
||||
cmd string
|
||||
@@ -87,15 +86,14 @@ func TestIncrByFloatExec(t *testing.T) {
|
||||
|
||||
for _, test := range tests {
|
||||
t.Run(test.cmd, func(t *testing.T) {
|
||||
_ = db.Str().Set("age", 25)
|
||||
_ = red.Str().Set("age", 25)
|
||||
|
||||
conn := redis.NewFakeConn()
|
||||
cmd := redis.MustParse(ParseIncrByFloat, test.cmd)
|
||||
res, err := cmd.Run(conn, red)
|
||||
testx.AssertNoErr(t, err)
|
||||
testx.AssertEqual(t, res, test.res)
|
||||
testx.AssertEqual(t, conn.Out(), test.out)
|
||||
be.Err(t, err, nil)
|
||||
be.Equal(t, res, test.res)
|
||||
be.Equal(t, conn.Out(), test.out)
|
||||
})
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -3,9 +3,9 @@ package string
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/nalgeon/be"
|
||||
"github.com/nalgeon/redka/internal/core"
|
||||
"github.com/nalgeon/redka/internal/redis"
|
||||
"github.com/nalgeon/redka/internal/testx"
|
||||
)
|
||||
|
||||
func TestMGetParse(t *testing.T) {
|
||||
@@ -34,22 +34,21 @@ func TestMGetParse(t *testing.T) {
|
||||
for _, test := range tests {
|
||||
t.Run(test.cmd, func(t *testing.T) {
|
||||
cmd, err := redis.Parse(ParseMGet, test.cmd)
|
||||
testx.AssertEqual(t, err, test.err)
|
||||
be.Equal(t, err, test.err)
|
||||
if err == nil {
|
||||
testx.AssertEqual(t, cmd.keys, test.want)
|
||||
be.Equal(t, cmd.keys, test.want)
|
||||
} else {
|
||||
testx.AssertEqual(t, cmd, MGet{})
|
||||
be.Equal(t, cmd, MGet{})
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestMGetExec(t *testing.T) {
|
||||
db, red := getDB(t)
|
||||
defer db.Close()
|
||||
red := getRedka(t)
|
||||
|
||||
_ = db.Str().Set("name", "alice")
|
||||
_ = db.Str().Set("age", 25)
|
||||
_ = red.Str().Set("name", "alice")
|
||||
_ = red.Str().Set("age", 25)
|
||||
|
||||
tests := []struct {
|
||||
cmd string
|
||||
@@ -83,9 +82,9 @@ func TestMGetExec(t *testing.T) {
|
||||
conn := redis.NewFakeConn()
|
||||
cmd := redis.MustParse(ParseMGet, test.cmd)
|
||||
res, err := cmd.Run(conn, red)
|
||||
testx.AssertNoErr(t, err)
|
||||
testx.AssertEqual(t, res, test.res)
|
||||
testx.AssertEqual(t, conn.Out(), test.out)
|
||||
be.Err(t, err, nil)
|
||||
be.Equal(t, res, test.res)
|
||||
be.Equal(t, conn.Out(), test.out)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3,8 +3,8 @@ package string
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/nalgeon/be"
|
||||
"github.com/nalgeon/redka/internal/redis"
|
||||
"github.com/nalgeon/redka/internal/testx"
|
||||
)
|
||||
|
||||
func TestMSetParse(t *testing.T) {
|
||||
@@ -46,11 +46,11 @@ func TestMSetParse(t *testing.T) {
|
||||
for _, test := range tests {
|
||||
t.Run(test.cmd, func(t *testing.T) {
|
||||
cmd, err := redis.Parse(ParseMSet, test.cmd)
|
||||
testx.AssertEqual(t, err, test.err)
|
||||
be.Equal(t, err, test.err)
|
||||
if err == nil {
|
||||
testx.AssertEqual(t, cmd.items, test.want.items)
|
||||
be.Equal(t, cmd.items, test.want.items)
|
||||
} else {
|
||||
testx.AssertEqual(t, cmd, test.want)
|
||||
be.Equal(t, cmd, test.want)
|
||||
}
|
||||
})
|
||||
}
|
||||
@@ -58,73 +58,69 @@ func TestMSetParse(t *testing.T) {
|
||||
|
||||
func TestMSetExec(t *testing.T) {
|
||||
t.Run("create single", func(t *testing.T) {
|
||||
db, red := getDB(t)
|
||||
defer db.Close()
|
||||
red := getRedka(t)
|
||||
|
||||
cmd := redis.MustParse(ParseMSet, "mset name alice")
|
||||
conn := redis.NewFakeConn()
|
||||
res, err := cmd.Run(conn, red)
|
||||
testx.AssertNoErr(t, err)
|
||||
testx.AssertEqual(t, res, true)
|
||||
testx.AssertEqual(t, conn.Out(), "OK")
|
||||
be.Err(t, err, nil)
|
||||
be.Equal(t, res, true)
|
||||
be.Equal(t, conn.Out(), "OK")
|
||||
|
||||
name, _ := db.Str().Get("name")
|
||||
testx.AssertEqual(t, name.String(), "alice")
|
||||
name, _ := red.Str().Get("name")
|
||||
be.Equal(t, name.String(), "alice")
|
||||
})
|
||||
|
||||
t.Run("create multiple", func(t *testing.T) {
|
||||
db, red := getDB(t)
|
||||
defer db.Close()
|
||||
red := getRedka(t)
|
||||
|
||||
cmd := redis.MustParse(ParseMSet, "mset name alice age 25")
|
||||
conn := redis.NewFakeConn()
|
||||
res, err := cmd.Run(conn, red)
|
||||
testx.AssertNoErr(t, err)
|
||||
testx.AssertEqual(t, res, true)
|
||||
testx.AssertEqual(t, conn.Out(), "OK")
|
||||
be.Err(t, err, nil)
|
||||
be.Equal(t, res, true)
|
||||
be.Equal(t, conn.Out(), "OK")
|
||||
|
||||
name, _ := db.Str().Get("name")
|
||||
testx.AssertEqual(t, name.String(), "alice")
|
||||
age, _ := db.Str().Get("age")
|
||||
testx.AssertEqual(t, age.String(), "25")
|
||||
name, _ := red.Str().Get("name")
|
||||
be.Equal(t, name.String(), "alice")
|
||||
age, _ := red.Str().Get("age")
|
||||
be.Equal(t, age.String(), "25")
|
||||
})
|
||||
|
||||
t.Run("create/update", func(t *testing.T) {
|
||||
db, red := getDB(t)
|
||||
defer db.Close()
|
||||
red := getRedka(t)
|
||||
|
||||
_ = db.Str().Set("name", "alice")
|
||||
_ = red.Str().Set("name", "alice")
|
||||
|
||||
cmd := redis.MustParse(ParseMSet, "mset name bob age 50")
|
||||
conn := redis.NewFakeConn()
|
||||
res, err := cmd.Run(conn, red)
|
||||
testx.AssertNoErr(t, err)
|
||||
testx.AssertEqual(t, res, true)
|
||||
testx.AssertEqual(t, conn.Out(), "OK")
|
||||
be.Err(t, err, nil)
|
||||
be.Equal(t, res, true)
|
||||
be.Equal(t, conn.Out(), "OK")
|
||||
|
||||
name, _ := db.Str().Get("name")
|
||||
testx.AssertEqual(t, name.String(), "bob")
|
||||
age, _ := db.Str().Get("age")
|
||||
testx.AssertEqual(t, age.String(), "50")
|
||||
name, _ := red.Str().Get("name")
|
||||
be.Equal(t, name.String(), "bob")
|
||||
age, _ := red.Str().Get("age")
|
||||
be.Equal(t, age.String(), "50")
|
||||
})
|
||||
|
||||
t.Run("update multiple", func(t *testing.T) {
|
||||
db, red := getDB(t)
|
||||
defer db.Close()
|
||||
red := getRedka(t)
|
||||
|
||||
_ = db.Str().Set("name", "alice")
|
||||
_ = db.Str().Set("age", 25)
|
||||
_ = red.Str().Set("name", "alice")
|
||||
_ = red.Str().Set("age", 25)
|
||||
|
||||
cmd := redis.MustParse(ParseMSet, "mset name bob age 50")
|
||||
conn := redis.NewFakeConn()
|
||||
res, err := cmd.Run(conn, red)
|
||||
testx.AssertNoErr(t, err)
|
||||
testx.AssertEqual(t, res, true)
|
||||
testx.AssertEqual(t, conn.Out(), "OK")
|
||||
be.Err(t, err, nil)
|
||||
be.Equal(t, res, true)
|
||||
be.Equal(t, conn.Out(), "OK")
|
||||
|
||||
name, _ := db.Str().Get("name")
|
||||
testx.AssertEqual(t, name.String(), "bob")
|
||||
age, _ := db.Str().Get("age")
|
||||
testx.AssertEqual(t, age.String(), "50")
|
||||
name, _ := red.Str().Get("name")
|
||||
be.Equal(t, name.String(), "bob")
|
||||
age, _ := red.Str().Get("age")
|
||||
be.Equal(t, age.String(), "50")
|
||||
})
|
||||
}
|
||||
|
||||
@@ -4,8 +4,8 @@ import (
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"github.com/nalgeon/be"
|
||||
"github.com/nalgeon/redka/internal/redis"
|
||||
"github.com/nalgeon/redka/internal/testx"
|
||||
)
|
||||
|
||||
func TestPSetEXParse(t *testing.T) {
|
||||
@@ -48,13 +48,13 @@ func TestPSetEXParse(t *testing.T) {
|
||||
for _, test := range tests {
|
||||
t.Run(test.cmd, func(t *testing.T) {
|
||||
cmd, err := redis.Parse(parse, test.cmd)
|
||||
testx.AssertEqual(t, err, test.err)
|
||||
be.Equal(t, err, test.err)
|
||||
if err == nil {
|
||||
testx.AssertEqual(t, cmd.key, test.want.key)
|
||||
testx.AssertEqual(t, cmd.value, test.want.value)
|
||||
testx.AssertEqual(t, cmd.ttl, test.want.ttl)
|
||||
be.Equal(t, cmd.key, test.want.key)
|
||||
be.Equal(t, cmd.value, test.want.value)
|
||||
be.Equal(t, cmd.ttl, test.want.ttl)
|
||||
} else {
|
||||
testx.AssertEqual(t, cmd, test.want)
|
||||
be.Equal(t, cmd, test.want)
|
||||
}
|
||||
})
|
||||
}
|
||||
@@ -66,64 +66,59 @@ func TestPSetEXExec(t *testing.T) {
|
||||
}
|
||||
|
||||
t.Run("create", func(t *testing.T) {
|
||||
db, red := getDB(t)
|
||||
defer db.Close()
|
||||
red := getRedka(t)
|
||||
|
||||
cmd := redis.MustParse(parse, "psetex name 60000 alice")
|
||||
conn := redis.NewFakeConn()
|
||||
res, err := cmd.Run(conn, red)
|
||||
testx.AssertNoErr(t, err)
|
||||
testx.AssertEqual(t, res, true)
|
||||
testx.AssertEqual(t, conn.Out(), "OK")
|
||||
be.Err(t, err, nil)
|
||||
be.Equal(t, res, true)
|
||||
be.Equal(t, conn.Out(), "OK")
|
||||
|
||||
expireAt := time.Now().Add(60 * time.Second)
|
||||
key, _ := db.Key().Get("name")
|
||||
testx.AssertEqual(t, *key.ETime/1000, expireAt.UnixMilli()/1000)
|
||||
key, _ := red.Key().Get("name")
|
||||
be.Equal(t, *key.ETime/1000, expireAt.UnixMilli()/1000)
|
||||
|
||||
name, _ := db.Str().Get("name")
|
||||
testx.AssertEqual(t, name.String(), "alice")
|
||||
name, _ := red.Str().Get("name")
|
||||
be.Equal(t, name.String(), "alice")
|
||||
})
|
||||
|
||||
t.Run("update", func(t *testing.T) {
|
||||
db, red := getDB(t)
|
||||
defer db.Close()
|
||||
|
||||
_ = db.Str().Set("name", "alice")
|
||||
red := getRedka(t)
|
||||
_ = red.Str().Set("name", "alice")
|
||||
|
||||
cmd := redis.MustParse(parse, "psetex name 60000 bob")
|
||||
conn := redis.NewFakeConn()
|
||||
res, err := cmd.Run(conn, red)
|
||||
testx.AssertNoErr(t, err)
|
||||
testx.AssertEqual(t, res, true)
|
||||
testx.AssertEqual(t, conn.Out(), "OK")
|
||||
be.Err(t, err, nil)
|
||||
be.Equal(t, res, true)
|
||||
be.Equal(t, conn.Out(), "OK")
|
||||
|
||||
expireAt := time.Now().Add(60 * time.Second)
|
||||
key, _ := db.Key().Get("name")
|
||||
testx.AssertEqual(t, *key.ETime/1000, expireAt.UnixMilli()/1000)
|
||||
key, _ := red.Key().Get("name")
|
||||
be.Equal(t, *key.ETime/1000, expireAt.UnixMilli()/1000)
|
||||
|
||||
name, _ := db.Str().Get("name")
|
||||
testx.AssertEqual(t, name.String(), "bob")
|
||||
name, _ := red.Str().Get("name")
|
||||
be.Equal(t, name.String(), "bob")
|
||||
})
|
||||
|
||||
t.Run("change ttl", func(t *testing.T) {
|
||||
db, red := getDB(t)
|
||||
defer db.Close()
|
||||
|
||||
_ = db.Str().SetExpires("name", "alice", 60*time.Second)
|
||||
red := getRedka(t)
|
||||
_ = red.Str().SetExpires("name", "alice", 60*time.Second)
|
||||
|
||||
cmd := redis.MustParse(parse, "psetex name 10000 bob")
|
||||
conn := redis.NewFakeConn()
|
||||
res, err := cmd.Run(conn, red)
|
||||
testx.AssertNoErr(t, err)
|
||||
testx.AssertEqual(t, res, true)
|
||||
testx.AssertEqual(t, conn.Out(), "OK")
|
||||
be.Err(t, err, nil)
|
||||
be.Equal(t, res, true)
|
||||
be.Equal(t, conn.Out(), "OK")
|
||||
|
||||
expireAt := time.Now().Add(10 * time.Second)
|
||||
key, _ := db.Key().Get("name")
|
||||
testx.AssertEqual(t, *key.ETime/1000, expireAt.UnixMilli()/1000)
|
||||
key, _ := red.Key().Get("name")
|
||||
be.Equal(t, *key.ETime/1000, expireAt.UnixMilli()/1000)
|
||||
|
||||
name, _ := db.Str().Get("name")
|
||||
testx.AssertEqual(t, name.String(), "bob")
|
||||
name, _ := red.Str().Get("name")
|
||||
be.Equal(t, name.String(), "bob")
|
||||
})
|
||||
|
||||
}
|
||||
|
||||
@@ -4,9 +4,9 @@ import (
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"github.com/nalgeon/be"
|
||||
"github.com/nalgeon/redka/internal/core"
|
||||
"github.com/nalgeon/redka/internal/redis"
|
||||
"github.com/nalgeon/redka/internal/testx"
|
||||
)
|
||||
|
||||
func TestSetParse(t *testing.T) {
|
||||
@@ -123,23 +123,22 @@ func TestSetParse(t *testing.T) {
|
||||
for _, test := range tests {
|
||||
t.Run(test.cmd, func(t *testing.T) {
|
||||
cmd, err := redis.Parse(ParseSet, test.cmd)
|
||||
testx.AssertEqual(t, err, test.err)
|
||||
be.Equal(t, err, test.err)
|
||||
if err == nil {
|
||||
testx.AssertEqual(t, cmd.key, test.want.key)
|
||||
testx.AssertEqual(t, cmd.value, test.want.value)
|
||||
testx.AssertEqual(t, cmd.ifNX, test.want.ifNX)
|
||||
testx.AssertEqual(t, cmd.ifXX, test.want.ifXX)
|
||||
testx.AssertEqual(t, cmd.ttl, test.want.ttl)
|
||||
be.Equal(t, cmd.key, test.want.key)
|
||||
be.Equal(t, cmd.value, test.want.value)
|
||||
be.Equal(t, cmd.ifNX, test.want.ifNX)
|
||||
be.Equal(t, cmd.ifXX, test.want.ifXX)
|
||||
be.Equal(t, cmd.ttl, test.want.ttl)
|
||||
} else {
|
||||
testx.AssertEqual(t, cmd, test.want)
|
||||
be.Equal(t, cmd, test.want)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestSetExec(t *testing.T) {
|
||||
db, red := getDB(t)
|
||||
defer db.Close()
|
||||
red := getRedka(t)
|
||||
|
||||
tests := []struct {
|
||||
cmd string
|
||||
@@ -203,9 +202,9 @@ func TestSetExec(t *testing.T) {
|
||||
conn := redis.NewFakeConn()
|
||||
cmd := redis.MustParse(ParseSet, test.cmd)
|
||||
res, err := cmd.Run(conn, red)
|
||||
testx.AssertNoErr(t, err)
|
||||
testx.AssertEqual(t, res, test.res)
|
||||
testx.AssertEqual(t, conn.Out(), test.out)
|
||||
be.Err(t, err, nil)
|
||||
be.Equal(t, res, test.res)
|
||||
be.Equal(t, conn.Out(), test.out)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user