mirror of
https://github.com/swift-server/RediStack.git
synced 2026-06-02 07:37:33 +00:00
337 lines
13 KiB
Swift
337 lines
13 KiB
Swift
//===----------------------------------------------------------------------===//
|
|
//
|
|
// This source file is part of the RediStack open source project
|
|
//
|
|
// Copyright (c) 2019-2020 RediStack project authors
|
|
// Licensed under Apache License v2.0
|
|
//
|
|
// See LICENSE.txt for license information
|
|
// See CONTRIBUTORS.txt for the list of RediStack project authors
|
|
//
|
|
// SPDX-License-Identifier: Apache-2.0
|
|
//
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
@testable import RediStack
|
|
import RediStackTestUtils
|
|
import XCTest
|
|
|
|
final class ListCommandsTests: RediStackIntegrationTestCase {
|
|
func test_llen() throws {
|
|
var length = try connection.send(.llen(of: #function)).wait()
|
|
XCTAssertEqual(length, 0)
|
|
_ = try connection.send(.lpush([30], into: #function)).wait()
|
|
length = try connection.send(.llen(of: #function)).wait()
|
|
XCTAssertEqual(length, 1)
|
|
}
|
|
|
|
func test_lindex() throws {
|
|
var element = try connection.send(.lindex(0, from: #function)).wait()
|
|
XCTAssertNil(element)
|
|
|
|
_ = try connection.send(.lpush([10], into: #function)).wait()
|
|
|
|
element = try connection.send(.lindex(0, from: #function)).wait()
|
|
XCTAssertNotNil(element)
|
|
XCTAssertEqual(Int(fromRESP: try XCTUnwrap(element)), 10)
|
|
}
|
|
|
|
func test_lset() throws {
|
|
XCTAssertThrowsError(try connection.send(.lset(index: 0, to: 30, in: #function)).wait())
|
|
_ = try connection.send(.lpush([10], into: #function)).wait()
|
|
XCTAssertNoThrow(try connection.send(.lset(index: 0, to: 30, in: #function)).wait())
|
|
let element = try connection.send(.lindex(0, from: #function)).wait()
|
|
XCTAssertEqual(Int(fromRESP: try XCTUnwrap(element)), 30)
|
|
}
|
|
|
|
func test_lrem() throws {
|
|
_ = try connection.send(.lpush([10, 10, 20, 30, 10], into: #function)).wait()
|
|
var count = try connection.send(.lrem(10, from: #function, count: 2)).wait()
|
|
XCTAssertEqual(count, 2)
|
|
count = try connection.send(.lrem(10, from: #function, count: 2)).wait()
|
|
XCTAssertEqual(count, 1)
|
|
}
|
|
|
|
func test_lrange() throws {
|
|
var elements = try connection.send(.lrange(from: #function, indices: 0...10)).wait()
|
|
XCTAssertEqual(elements.count, 0)
|
|
|
|
_ = try connection.send(.lpush([5, 4, 3, 2, 1], into: #function)).wait()
|
|
|
|
elements = try connection.send(.lrange(from: #function, throughIndex: 4)).wait()
|
|
XCTAssertEqual(elements.count, 5)
|
|
XCTAssertEqual(Int(fromRESP: elements[0]), 1)
|
|
XCTAssertEqual(Int(fromRESP: elements[4]), 5)
|
|
|
|
elements = try connection.send(.lrange(from: #function, fromIndex: 1)).wait()
|
|
XCTAssertEqual(elements.count, 4)
|
|
elements = try connection.send(.lrange(from: #function, fromIndex: -3)).wait()
|
|
XCTAssertEqual(elements.count, 3)
|
|
|
|
elements = try connection.send(.lrange(from: #function, firstIndex: 2, lastIndex: 0)).wait()
|
|
XCTAssertEqual(elements.count, 0)
|
|
|
|
elements = try connection.send(.lrange(from: #function, indices: 4...5)).wait()
|
|
XCTAssertEqual(elements.count, 1)
|
|
|
|
elements = try connection.send(.lrange(from: #function, upToIndex: -3)).wait()
|
|
XCTAssertEqual(elements.count, 2)
|
|
}
|
|
|
|
func test_rpoplpush() throws {
|
|
_ = try connection.send(.lpush([10], into: "first")).wait()
|
|
_ = try connection.send(.lpush([30], into: "second")).wait()
|
|
|
|
var element = try connection.send(.rpoplpush(from: "first", to: "second")).wait()
|
|
XCTAssertEqual(Int(fromRESP: try XCTUnwrap(element)), 10)
|
|
XCTAssertEqual(try connection.send(.llen(of: "first")).wait(), 0)
|
|
XCTAssertEqual(try connection.send(.llen(of: "second")).wait(), 2)
|
|
|
|
element = try connection.send(.rpoplpush(from: "second", to: "first")).wait()
|
|
XCTAssertEqual(Int(fromRESP: try XCTUnwrap(element)), 30)
|
|
XCTAssertEqual(try connection.send(.llen(of: "second")).wait(), 1)
|
|
}
|
|
|
|
func test_brpoplpush() throws {
|
|
_ = try connection.send(.lpush([10], into: "first")).wait()
|
|
|
|
let element = try connection.send(.brpoplpush(from: "first", to: "second")).wait()
|
|
XCTAssertEqual(Int(fromRESP: try XCTUnwrap(element)), 10)
|
|
|
|
let blockingConnection = try self.makeNewConnection()
|
|
let expectation = XCTestExpectation(description: "brpoplpush should never return")
|
|
_ = blockingConnection.send(.bzpopmin(from: #function))
|
|
.always { _ in
|
|
expectation.fulfill()
|
|
blockingConnection.close()
|
|
}
|
|
|
|
let result = XCTWaiter.wait(for: [expectation], timeout: 1)
|
|
XCTAssertEqual(result, .timedOut)
|
|
}
|
|
|
|
func test_linsert() throws {
|
|
_ = try connection.send(.lpush([10], into: #function)).wait()
|
|
|
|
_ = try connection.send(.linsert(20, into: #function, after: 10)).wait()
|
|
var elements = try connection.send(.lrange(from: #function, throughIndex: 1))
|
|
.map { response in response.compactMap { Int(fromRESP: $0) } }
|
|
.wait()
|
|
XCTAssertEqual(elements, [10, 20])
|
|
|
|
_ = try connection.send(.linsert(30, into: #function, before: 10)).wait()
|
|
elements = try connection.send(.lrange(from: #function, throughIndex: 2))
|
|
.map { response in response.compactMap { Int(fromRESP: $0) } }
|
|
.wait()
|
|
XCTAssertEqual(elements, [30, 10, 20])
|
|
}
|
|
|
|
func test_lpop() throws {
|
|
var element = try connection.send(.lpop(from: #function)).wait()
|
|
XCTAssertNil(element)
|
|
|
|
_ = try connection.send(.lpush([10, 20, 30], into: #function)).wait()
|
|
|
|
element = try connection.send(.lpop(from: #function)).wait()
|
|
XCTAssertNotNil(element)
|
|
XCTAssertEqual(Int(fromRESP: try XCTUnwrap(element)), 30)
|
|
}
|
|
|
|
func test_blpop() throws {
|
|
let nilPop = try connection.send(.blpop(from: #function, timeout: .seconds(1))).wait()
|
|
XCTAssertNil(nilPop)
|
|
|
|
_ = try connection.send(.lpush([10, 20, 30], into: "first")).wait()
|
|
let pop1 = try connection.send(.blpop(from: "first")).wait()
|
|
XCTAssertEqual(Int(fromRESP: try XCTUnwrap(pop1)), 30)
|
|
|
|
let pop2 = try connection.send(.blpop(from: "fake", "first")).wait()
|
|
XCTAssertEqual(pop2?.0, "first")
|
|
|
|
let blockingConnection = try self.makeNewConnection()
|
|
let expectation = XCTestExpectation(description: "blpop should never return")
|
|
_ = blockingConnection.send(.bzpopmin(from: #function))
|
|
.always { _ in
|
|
expectation.fulfill()
|
|
blockingConnection.close()
|
|
}
|
|
|
|
let result = XCTWaiter.wait(for: [expectation], timeout: 1)
|
|
XCTAssertEqual(result, .timedOut)
|
|
}
|
|
|
|
func test_lpush() throws {
|
|
_ = try connection.send(.rpush([10, 20, 30], into: #function)).wait()
|
|
|
|
let size = try connection.send(.lpush(100, into: #function)).wait()
|
|
let element = try connection.send(.lindex(0, from: #function)).wait()
|
|
XCTAssertEqual(size, 4)
|
|
XCTAssertEqual(Int(fromRESP: try XCTUnwrap(element)), 100)
|
|
}
|
|
|
|
func test_lpushx() throws {
|
|
var size = try connection.send(.lpushx(10, into: #function)).wait()
|
|
XCTAssertEqual(size, 0)
|
|
|
|
_ = try connection.send(.lpush([10], into: #function)).wait()
|
|
|
|
size = try connection.send(.lpushx(30, into: #function)).wait()
|
|
XCTAssertEqual(size, 2)
|
|
let element = try connection.send(.rpop(from: #function))
|
|
.flatMapThrowing { return Int(fromRESP: try XCTUnwrap($0)) }
|
|
.wait()
|
|
XCTAssertEqual(element, 10)
|
|
}
|
|
|
|
func test_rpop() throws {
|
|
_ = try connection.send(.lpush([10, 20, 30], into: #function)).wait()
|
|
|
|
let element = try connection.send(.rpop(from: #function)).wait()
|
|
XCTAssertNotNil(element)
|
|
XCTAssertEqual(Int(fromRESP: element!), 10)
|
|
|
|
_ = try connection.delete([#function]).wait()
|
|
|
|
let result = try connection.send(.rpop(from: #function)).wait()
|
|
XCTAssertNil(result)
|
|
}
|
|
|
|
func test_brpop() throws {
|
|
let nilPop = try connection.send(.brpop(from: #function, timeout: .seconds(1))).wait()
|
|
XCTAssertNil(nilPop)
|
|
|
|
_ = try connection.send(.lpush([10, 20, 30], into: "first")).wait()
|
|
let pop1 = try connection.send(.brpop(from: "first")).wait()
|
|
XCTAssertEqual(Int(fromRESP: try XCTUnwrap(pop1)), 10)
|
|
|
|
let pop2 = try connection.send(.brpop(from: "fake", "first")).wait()
|
|
XCTAssertEqual(pop2?.0, "first")
|
|
|
|
let blockingConnection = try self.makeNewConnection()
|
|
let expectation = XCTestExpectation(description: "brpop should never return")
|
|
_ = blockingConnection.send(.bzpopmin(from: #function))
|
|
.always { _ in
|
|
expectation.fulfill()
|
|
blockingConnection.close()
|
|
}
|
|
|
|
let result = XCTWaiter.wait(for: [expectation], timeout: 1)
|
|
XCTAssertEqual(result, .timedOut)
|
|
}
|
|
|
|
func test_rpush() throws {
|
|
_ = try connection.send(.lpush([10, 20, 30], into: #function)).wait()
|
|
|
|
let size = try connection.send(.rpush(100, into: #function)).wait()
|
|
let element = try connection.send(.lindex(3, from: #function)).wait()
|
|
XCTAssertEqual(size, 4)
|
|
XCTAssertEqual(Int(fromRESP: try XCTUnwrap(element)), 100)
|
|
}
|
|
|
|
func test_rpushx() throws {
|
|
var size = try connection.send(.rpushx(10, into: #function)).wait()
|
|
XCTAssertEqual(size, 0)
|
|
|
|
_ = try connection.send(.rpush([10], into: #function)).wait()
|
|
|
|
size = try connection.send(.rpushx(30, into: #function)).wait()
|
|
XCTAssertEqual(size, 2)
|
|
let element = try connection.send(.lpop(from: #function))
|
|
.flatMapThrowing { return Int(fromRESP: try XCTUnwrap($0)) }
|
|
.wait()
|
|
XCTAssertEqual(element, 10)
|
|
}
|
|
|
|
func test_ltrim() throws {
|
|
let setup = {
|
|
_ = try self.connection.delete(#function).wait()
|
|
_ = try self.connection.send(.lpush([5, 4, 3, 2, 1], into: #function)).wait()
|
|
}
|
|
let getElements = { return try self.connection.send(.lrange(from: #function, fromIndex: 0)).wait() }
|
|
|
|
try setup()
|
|
|
|
XCTAssertNoThrow(try connection.send(.ltrim(#function, before: 1, after: 3)).wait())
|
|
XCTAssertNoThrow(try connection.send(.ltrim(#function, keepingIndices: 0...1)).wait())
|
|
var elements = try getElements()
|
|
XCTAssertEqual(elements.count, 2)
|
|
|
|
try setup()
|
|
|
|
XCTAssertNoThrow(try connection.send(.ltrim(#function, keepingIndices: (-3)...)).wait())
|
|
elements = try getElements()
|
|
XCTAssertEqual(elements.count, 3)
|
|
|
|
try setup()
|
|
|
|
XCTAssertNoThrow(try connection.send(.ltrim(#function, keepingIndices: ...(-4))).wait())
|
|
elements = try getElements()
|
|
XCTAssertEqual(elements.count, 2)
|
|
|
|
try setup()
|
|
XCTAssertNoThrow(try connection.send(.ltrim(#function, keepingIndices: ..<(-2))).wait())
|
|
elements = try getElements()
|
|
XCTAssertEqual(elements.count, 3)
|
|
}
|
|
}
|
|
|
|
// MARK: #116 tests
|
|
|
|
extension ListCommandsTests {
|
|
func test_rpoplpush_whenEmpty_succeeds_withNil() throws {
|
|
let result = try self
|
|
.connection
|
|
.send(.rpoplpush(from: "list1", to: "\(#function)"))
|
|
.wait()
|
|
XCTAssertNil(result)
|
|
}
|
|
|
|
func test_rpop_whenEmpty_succeeds_withNil() throws {
|
|
let result = try self
|
|
.connection
|
|
.send(.rpop(from: "\(#function)"))
|
|
.wait()
|
|
XCTAssertNil(result)
|
|
}
|
|
|
|
func test_lpop_whenEmpty_succeeds_withNil() throws {
|
|
let result = try self
|
|
.connection
|
|
.send(.lpop(from: "\(#function)"))
|
|
.wait()
|
|
XCTAssertNil(result)
|
|
}
|
|
|
|
func test_lindex_whenEmpty_succeeds_withNil() throws {
|
|
let result = try self
|
|
.connection
|
|
.send(.lindex(3, from: "\(#function)"))
|
|
.wait()
|
|
XCTAssertNil(result)
|
|
}
|
|
|
|
func test_lrange_whenEmpty_succeeds_withEmpty() throws {
|
|
let result = try self
|
|
.connection
|
|
.send(.lrange(from: "\(#function)", firstIndex: 0, lastIndex: 3))
|
|
.wait()
|
|
XCTAssertTrue(result.isEmpty)
|
|
}
|
|
|
|
func test_brpoplpush_whenEmpty_succeeds_withNil() throws {
|
|
let result = try self
|
|
.connection
|
|
.send(.brpoplpush(from: "\(#function)", to: "list1", timeout: .seconds(1)))
|
|
.wait()
|
|
XCTAssertNil(result)
|
|
}
|
|
|
|
func test_brpop_whenEmpty_succeeds_withNil() throws {
|
|
let result = try self
|
|
.connection
|
|
.send(.brpop(from: "\(#function)", timeout: .seconds(1)))
|
|
.wait()
|
|
XCTAssertNil(result)
|
|
}
|
|
}
|