jetstream 16.0.0

Jetstream is a RPC framework for Rust, based on the 9P protocol and QUIC.
Documentation
// JetStream WireFormat — Error Type Tests
// Copyright (c) 2024, Sevki <s@sevki.io>
// SPDX-License-Identifier: BSD-3-Clause

import XCTest
@testable import JetStreamWireFormat

final class ErrorTests: XCTestCase {

    // MARK: - Level

    // r[verify jetstream.wireformat.swift.level]
    // r[verify jetstream.wireformat.level]
    func testLevelRoundTrip() throws {
        for level in [Level.trace, .debug, .info, .warn, .error] {
            var writer = BinaryWriter()
            try level.encode(writer: &writer)
            var reader = BinaryReader(data: writer.data)
            let decoded = try Level.decode(reader: &reader)
            XCTAssertEqual(decoded, level)
        }
    }

    func testLevelEncoding() throws {
        var writer = BinaryWriter()
        try Level.error.encode(writer: &writer)
        XCTAssertEqual(writer.data, Data([4]))
    }

    // r[verify jetstream.wireformat.swift.test-error]
    func testLevelInvalidValue() throws {
        var reader = BinaryReader(data: Data([5]))
        XCTAssertThrowsError(try Level.decode(reader: &reader)) { error in
            XCTAssertEqual(error as? WireFormatError, WireFormatError.invalidLevelValue(5))
        }
    }

    // MARK: - FieldPair

    // r[verify jetstream.wireformat.swift.fieldpair]
    // r[verify jetstream.wireformat.fieldpair]
    func testFieldPairRoundTrip() throws {
        let pair = FieldPair(key: 1, value: 2)
        var writer = BinaryWriter()
        try pair.encode(writer: &writer)
        var reader = BinaryReader(data: writer.data)
        let decoded = try FieldPair.decode(reader: &reader)
        XCTAssertEqual(decoded, pair)
    }

    func testFieldPairByteSize() {
        XCTAssertEqual(FieldPair(key: 0, value: 0).byteSize(), 4)
    }

    // MARK: - Frame

    // r[verify jetstream.wireformat.swift.frame]
    // r[verify jetstream.wireformat.frame]
    func testFrameRoundTrip() throws {
        let frame = Frame(
            msg: "test span",
            name: 1,
            target: 2,
            module: 3,
            file: 4,
            line: 42,
            fields: [FieldPair(key: 5, value: 6)],
            level: .info
        )
        var writer = BinaryWriter()
        try frame.encode(writer: &writer)
        var reader = BinaryReader(data: writer.data)
        let decoded = try Frame.decode(reader: &reader)
        XCTAssertEqual(decoded, frame)
    }

    func testFrameEmptyFields() throws {
        let frame = Frame(
            msg: "",
            name: 0,
            target: 0,
            module: 0,
            file: 0,
            line: 0,
            fields: [],
            level: .trace
        )
        var writer = BinaryWriter()
        try frame.encode(writer: &writer)
        var reader = BinaryReader(data: writer.data)
        let decoded = try Frame.decode(reader: &reader)
        XCTAssertEqual(decoded, frame)
    }

    // MARK: - Backtrace

    // r[verify jetstream.wireformat.swift.backtrace]
    // r[verify jetstream.wireformat.backtrace]
    func testBacktraceRoundTrip() throws {
        let bt = Backtrace(
            internTable: ["", "myFunc", "myModule", "src/main.swift"],
            frames: [
                Frame(
                    msg: "doing work",
                    name: 1,
                    target: 2,
                    module: 2,
                    file: 3,
                    line: 10,
                    fields: [],
                    level: .info
                ),
            ]
        )
        var writer = BinaryWriter()
        try bt.encode(writer: &writer)
        var reader = BinaryReader(data: writer.data)
        let decoded = try Backtrace.decode(reader: &reader)
        XCTAssertEqual(decoded, bt)
    }

    func testEmptyBacktrace() throws {
        let bt = Backtrace()
        var writer = BinaryWriter()
        try bt.encode(writer: &writer)
        var reader = BinaryReader(data: writer.data)
        let decoded = try Backtrace.decode(reader: &reader)
        XCTAssertEqual(decoded.internTable, [""])
        XCTAssertEqual(decoded.frames.count, 0)
    }

    // MARK: - ErrorInner

    // r[verify jetstream.wireformat.swift.error-inner]
    // r[verify jetstream.wireformat.error-inner]
    func testErrorInnerRoundTrip() throws {
        let inner = ErrorInner(
            message: "something went wrong",
            code: "E001",
            help: "try restarting",
            url: "https://example.com/help"
        )
        var writer = BinaryWriter()
        try inner.encode(writer: &writer)
        var reader = BinaryReader(data: writer.data)
        let decoded = try ErrorInner.decode(reader: &reader)
        XCTAssertEqual(decoded, inner)
    }

    func testErrorInnerMinimal() throws {
        let inner = ErrorInner(message: "error")
        var writer = BinaryWriter()
        try inner.encode(writer: &writer)
        var reader = BinaryReader(data: writer.data)
        let decoded = try ErrorInner.decode(reader: &reader)
        XCTAssertEqual(decoded.message, "error")
        XCTAssertNil(decoded.code)
        XCTAssertNil(decoded.help)
        XCTAssertNil(decoded.url)
    }

    // MARK: - JetStreamError

    // r[verify jetstream.wireformat.swift.error]
    // r[verify jetstream.wireformat.error]
    func testJetStreamErrorRoundTrip() throws {
        let err = JetStreamError(
            inner: ErrorInner(
                message: "connection failed",
                code: "CONN_ERR",
                help: nil,
                url: nil
            ),
            backtrace: Backtrace(
                internTable: ["", "connect", "network"],
                frames: [
                    Frame(
                        msg: "connecting",
                        name: 1,
                        target: 2,
                        module: 2,
                        file: 0,
                        line: 55,
                        fields: [],
                        level: .error
                    ),
                ]
            )
        )
        var writer = BinaryWriter()
        try err.encode(writer: &writer)
        var reader = BinaryReader(data: writer.data)
        let decoded = try JetStreamError.decode(reader: &reader)
        XCTAssertEqual(decoded, err)
    }

    func testJetStreamErrorMinimal() throws {
        let err = JetStreamError(inner: ErrorInner(message: "fail"))
        var writer = BinaryWriter()
        try err.encode(writer: &writer)
        var reader = BinaryReader(data: writer.data)
        let decoded = try JetStreamError.decode(reader: &reader)
        XCTAssertEqual(decoded.inner.message, "fail")
        XCTAssertEqual(decoded.backtrace.frames.count, 0)
    }

    func testJetStreamErrorIsSwiftError() {
        let err = JetStreamError(inner: ErrorInner(message: "test"))
        // Verify it conforms to Swift's Error protocol
        let _: Error = err
    }

    // r[verify jetstream.wireformat.swift.test-roundtrip]
    func testFullErrorByteSize() {
        let err = JetStreamError(
            inner: ErrorInner(message: "x"),
            backtrace: Backtrace()
        )
        // inner: "x" = 2+1=3, code=nil=1, help=nil=1, url=nil=1 => 6
        // backtrace: internTable=[""] => 2+2+0=4, frames=[] => 2 => 6
        // total = 6 + 6 = 12
        XCTAssertEqual(err.byteSize(), 12)
    }
}