swift-nio/Tests/NIOTestUtilsTests/ByteToMessageDecoderVerifie...

169 lines
7.1 KiB
Swift

//===----------------------------------------------------------------------===//
//
// This source file is part of the SwiftNIO open source project
//
// Copyright (c) 2019-2021 Apple Inc. and the SwiftNIO project authors
// Licensed under Apache License v2.0
//
// See LICENSE.txt for license information
// See CONTRIBUTORS.txt for the list of SwiftNIO project authors
//
// SPDX-License-Identifier: Apache-2.0
//
//===----------------------------------------------------------------------===//
@testable import NIOCore
import NIOPosix
import NIOTestUtils
import XCTest
typealias VerificationError = ByteToMessageDecoderVerifier.VerificationError<String>
class ByteToMessageDecoderVerifierTest: XCTestCase {
func testWrongResults() {
struct AlwaysProduceY: ByteToMessageDecoder {
typealias InboundOut = String
func decode(context: ChannelHandlerContext, buffer: inout ByteBuffer) throws -> DecodingState {
buffer.moveReaderIndex(to: buffer.writerIndex)
context.fireChannelRead(self.wrapInboundOut("Y"))
return .needMoreData
}
func decodeLast(context: ChannelHandlerContext,
buffer: inout ByteBuffer,
seenEOF: Bool) throws -> DecodingState {
while try self.decode(context: context, buffer: &buffer) == .continue {}
return .needMoreData
}
}
XCTAssertThrowsError(try ByteToMessageDecoderVerifier.verifyDecoder(stringInputOutputPairs: [("x", ["x"])],
decoderFactory: AlwaysProduceY.init)) {
error in
switch error {
case let error as VerificationError:
XCTAssertEqual(1, error.inputs.count)
switch error.errorCode {
case .wrongProduction(actual: let actual, expected: let expected):
XCTAssertEqual("Y", actual)
XCTAssertEqual("x", expected)
default:
XCTFail("unexpected error: \(error)")
}
default:
XCTFail("unexpected error: \(error)")
}
}
}
func testNoOutputWhenWeShouldHaveOutput() {
struct NeverProduce: ByteToMessageDecoder {
typealias InboundOut = String
func decode(context: ChannelHandlerContext, buffer: inout ByteBuffer) throws -> DecodingState {
buffer.moveReaderIndex(to: buffer.writerIndex)
return .needMoreData
}
func decodeLast(context: ChannelHandlerContext,
buffer: inout ByteBuffer,
seenEOF: Bool) throws -> DecodingState {
while try self.decode(context: context, buffer: &buffer) == .continue {}
return .needMoreData
}
}
XCTAssertThrowsError(try ByteToMessageDecoderVerifier.verifyDecoder(stringInputOutputPairs: [("x", ["x"])],
decoderFactory: NeverProduce.init)) {
error in
switch error {
case let error as VerificationError:
XCTAssertEqual(1, error.inputs.count)
switch error.errorCode {
case .underProduction(let expected):
XCTAssertEqual("x", expected)
default:
XCTFail("unexpected error: \(error)")
}
default:
XCTFail("unexpected error: \(error)")
}
}
}
func testOutputWhenWeShouldNotProduceOutput() {
struct ProduceTooEarly: ByteToMessageDecoder {
typealias InboundOut = String
func decode(context: ChannelHandlerContext, buffer: inout ByteBuffer) throws -> DecodingState {
context.fireChannelRead(self.wrapInboundOut("Y"))
return .needMoreData
}
func decodeLast(context: ChannelHandlerContext,
buffer: inout ByteBuffer,
seenEOF: Bool) throws -> DecodingState {
while try self.decode(context: context, buffer: &buffer) == .continue {}
return .needMoreData
}
}
XCTAssertThrowsError(try ByteToMessageDecoderVerifier.verifyDecoder(stringInputOutputPairs: [("xxxxxx", ["Y"])],
decoderFactory: ProduceTooEarly.init)) {
error in
switch error {
case let error as VerificationError:
switch error.errorCode {
case .overProduction(let actual):
XCTAssertEqual("Y", actual)
default:
XCTFail("unexpected error: \(error)")
}
default:
XCTFail("unexpected error: \(error)")
}
}
}
func testLeftovers() {
struct NeverDoAnything: ByteToMessageDecoder {
typealias InboundOut = String
func decode(context: ChannelHandlerContext, buffer: inout ByteBuffer) throws -> DecodingState {
return .needMoreData
}
func decodeLast(context: ChannelHandlerContext,
buffer: inout ByteBuffer,
seenEOF: Bool) throws -> DecodingState {
while try self.decode(context: context, buffer: &buffer) == .continue {}
if buffer.readableBytes > 0 {
context.fireChannelRead(self.wrapInboundOut("leftover"))
}
return .needMoreData
}
}
XCTAssertThrowsError(try ByteToMessageDecoderVerifier.verifyDecoder(stringInputOutputPairs: [("xxxxxx", [])],
decoderFactory: NeverDoAnything.init)) {
error in
switch error {
case let error as VerificationError:
switch error.errorCode {
case .leftOversOnDeconstructingChannel(inbound: let inbound,
outbound: let outbound,
pendingOutbound: let pending):
XCTAssertEqual(0, outbound.count)
XCTAssertEqual(["leftover"], inbound.map { $0.tryAs(type: String.self) })
XCTAssertEqual(0, pending.count)
default:
XCTFail("unexpected error: \(error)")
}
default:
XCTFail("unexpected error: \(error)")
}
}
}
}