From de74571576618265ac3032dbfa21ceba8385b09e Mon Sep 17 00:00:00 2001 From: Ucanbarlic Date: Tue, 3 Sep 2024 14:56:52 +0200 Subject: [PATCH 1/3] Making ByteBuffer's description more useful. Motivation: Resolving the following issue: https://github.com/apple/swift-nio/issues/2863 Modifications: Rewrote `description` and `debugDescription` on `ByteBuffer` to make it more useful. Result: A more userful `description` and `debugDescription`. After your change, what will change. --- Sources/NIOCore/ByteBuffer-core.swift | 29 +++++++++--------------- Sources/NIOCore/ByteBuffer-hexdump.swift | 2 +- Tests/NIOCoreTests/ByteBufferTest.swift | 14 +++++++++++- Tests/NIOCoreTests/NIOAnyDebugTest.swift | 2 +- 4 files changed, 26 insertions(+), 21 deletions(-) diff --git a/Sources/NIOCore/ByteBuffer-core.swift b/Sources/NIOCore/ByteBuffer-core.swift index 07f5847595..eee0c5427d 100644 --- a/Sources/NIOCore/ByteBuffer-core.swift +++ b/Sources/NIOCore/ByteBuffer-core.swift @@ -957,37 +957,30 @@ public struct ByteBuffer { } extension ByteBuffer: CustomStringConvertible, CustomDebugStringConvertible { - /// A `String` describing this `ByteBuffer`. Example: + /// A `String` describing this `ByteBuffer`. For a `ByteBuffer` initialised with `hello world` + /// the description would be the following: /// - /// ByteBuffer { readerIndex: 0, writerIndex: 4, readableBytes: 4, capacity: 512, storageCapacity: 1024, slice: 256..<768, storage: 0x0000000103001000 (1024 bytes)} + /// [68656c6c6f20776f726c64](11 bytes) /// + /// Buffers larger that 64 bytes will get truncated when printing out. /// The format of the description is not API. /// /// - returns: A description of this `ByteBuffer`. public var description: String { - """ - ByteBuffer { \ - readerIndex: \(self.readerIndex), \ - writerIndex: \(self.writerIndex), \ - readableBytes: \(self.readableBytes), \ - capacity: \(self.capacity), \ - storageCapacity: \(self.storageCapacity), \ - slice: \(self._slice), \ - storage: \(self._storage.bytes) (\(self._storage.capacity) bytes) \ - } - """ + "[\(self.hexDump(format: .compact(maxBytes: 64)))](\(self.readableBytes) bytes)" } - /// A `String` describing this `ByteBuffer` with some portion of the readable bytes dumped too. Example: + /// A `String` describing this `ByteBuffer`. For a `ByteBuffer` initialised with `hello world` + /// the description would be the following: /// - /// ByteBuffer { readerIndex: 0, writerIndex: 4, readableBytes: 4, capacity: 512, slice: 256..<768, storage: 0x0000000103001000 (1024 bytes)} - /// readable bytes (max 1k): [ 00 01 02 03 ] + /// [68656c6c6f20776f726c64](11 bytes) /// + /// Buffers larger that 64 bytes will get truncated when printing out. /// The format of the description is not API. /// - /// - returns: A description of this `ByteBuffer` useful for debugging. + /// - returns: A description of this `ByteBuffer`. public var debugDescription: String { - "\(self.description)\nreadable bytes (max 1k): \(self._storage.dumpBytes(slice: self._slice, offset: self.readerIndex, length: min(1024, self.readableBytes)))" + "[\(self.hexDump(format: .compact(maxBytes: 64)))](\(self.readableBytes) bytes)" } } diff --git a/Sources/NIOCore/ByteBuffer-hexdump.swift b/Sources/NIOCore/ByteBuffer-hexdump.swift index b938fe7799..3791b5e46a 100644 --- a/Sources/NIOCore/ByteBuffer-hexdump.swift +++ b/Sources/NIOCore/ByteBuffer-hexdump.swift @@ -93,7 +93,7 @@ extension ByteBuffer { private func _hexDump(maxBytes: Int, separateWithWhitespace: Bool) -> String { // If the buffer length fits in the max bytes limit in the hex dump, just dump the whole thing. if self.readableBytes <= maxBytes { - return self.hexDump(format: .plain) + return self._hexDump(separateWithWhitespace: separateWithWhitespace) } var buffer = self diff --git a/Tests/NIOCoreTests/ByteBufferTest.swift b/Tests/NIOCoreTests/ByteBufferTest.swift index aff6e05178..65ef550c93 100644 --- a/Tests/NIOCoreTests/ByteBufferTest.swift +++ b/Tests/NIOCoreTests/ByteBufferTest.swift @@ -1909,6 +1909,11 @@ class ByteBufferTest: XCTestCase { let buf = ByteBuffer(string: "Hello") XCTAssertEqual("48656c6c6f", buf.hexDump(format: .compact)) } + + func testHexDumpCompactReadableBytesLessThenMaxBytes() { + let buf = ByteBuffer(string: "hello world") + XCTAssertEqual("68656c6c6f20776f726c64", buf.hexDump(format: .compact(maxBytes: 100))) + } func testHexDumpCompactEmptyBuffer() { let buf = ByteBuffer(string: "") @@ -3602,5 +3607,12 @@ extension ByteBufferTest { XCTAssertEqual(error as? Base64Error, .invalidCharacter) } } - + + func testByteBufferDescription() { + let buffer = ByteBuffer(string: "hello world") + + XCTAssertEqual(buffer.description, "[68656c6c6f20776f726c64](11 bytes)") + + XCTAssertEqual(buffer.description, buffer.debugDescription) + } } diff --git a/Tests/NIOCoreTests/NIOAnyDebugTest.swift b/Tests/NIOCoreTests/NIOAnyDebugTest.swift index adf4c86976..cdf637affb 100644 --- a/Tests/NIOCoreTests/NIOAnyDebugTest.swift +++ b/Tests/NIOCoreTests/NIOAnyDebugTest.swift @@ -24,7 +24,7 @@ class NIOAnyDebugTest: XCTestCase { let bb = ByteBuffer(string: "byte buffer string") XCTAssertTrue( wrappedInNIOAnyBlock(bb).contains( - "NIOAny { ByteBuffer { readerIndex: 0, writerIndex: 18, readableBytes: 18, capacity: 32, storageCapacity: 32, slice: _ByteBufferSlice { 0..<32 }, storage: " + "NIOAny { [627974652062756666657220737472696e67](18 bytes) }" ) ) XCTAssertTrue(wrappedInNIOAnyBlock(bb).hasSuffix(" }")) From 961b455addb6306e24738cbac1dda16b69c2a8f4 Mon Sep 17 00:00:00 2001 From: Ucanbarlic Date: Wed, 4 Sep 2024 08:45:10 +0200 Subject: [PATCH 2/3] Improve doc comment --- Sources/NIOCore/ByteBuffer-core.swift | 10 ++++++---- Tests/NIOCoreTests/ByteBufferTest.swift | 8 ++++---- 2 files changed, 10 insertions(+), 8 deletions(-) diff --git a/Sources/NIOCore/ByteBuffer-core.swift b/Sources/NIOCore/ByteBuffer-core.swift index eee0c5427d..aaf19aea2d 100644 --- a/Sources/NIOCore/ByteBuffer-core.swift +++ b/Sources/NIOCore/ByteBuffer-core.swift @@ -957,8 +957,9 @@ public struct ByteBuffer { } extension ByteBuffer: CustomStringConvertible, CustomDebugStringConvertible { - /// A `String` describing this `ByteBuffer`. For a `ByteBuffer` initialised with `hello world` - /// the description would be the following: + /// A `String` describing this `ByteBuffer` including length and the bytes it contains (partially). + /// + /// For a `ByteBuffer` initialised with `hello world` the description would be the following: /// /// [68656c6c6f20776f726c64](11 bytes) /// @@ -970,8 +971,9 @@ extension ByteBuffer: CustomStringConvertible, CustomDebugStringConvertible { "[\(self.hexDump(format: .compact(maxBytes: 64)))](\(self.readableBytes) bytes)" } - /// A `String` describing this `ByteBuffer`. For a `ByteBuffer` initialised with `hello world` - /// the description would be the following: + /// A `String` describing this `ByteBuffer` including length and the bytes it contains (partially). + /// + /// For a `ByteBuffer` initialised with `hello world` the description would be the following: /// /// [68656c6c6f20776f726c64](11 bytes) /// diff --git a/Tests/NIOCoreTests/ByteBufferTest.swift b/Tests/NIOCoreTests/ByteBufferTest.swift index 65ef550c93..29a5af1a16 100644 --- a/Tests/NIOCoreTests/ByteBufferTest.swift +++ b/Tests/NIOCoreTests/ByteBufferTest.swift @@ -1909,7 +1909,7 @@ class ByteBufferTest: XCTestCase { let buf = ByteBuffer(string: "Hello") XCTAssertEqual("48656c6c6f", buf.hexDump(format: .compact)) } - + func testHexDumpCompactReadableBytesLessThenMaxBytes() { let buf = ByteBuffer(string: "hello world") XCTAssertEqual("68656c6c6f20776f726c64", buf.hexDump(format: .compact(maxBytes: 100))) @@ -3607,12 +3607,12 @@ extension ByteBufferTest { XCTAssertEqual(error as? Base64Error, .invalidCharacter) } } - + func testByteBufferDescription() { let buffer = ByteBuffer(string: "hello world") - + XCTAssertEqual(buffer.description, "[68656c6c6f20776f726c64](11 bytes)") - + XCTAssertEqual(buffer.description, buffer.debugDescription) } } From df18d08ffb6a3ed514c8c9e0dcf0077158b143df Mon Sep 17 00:00:00 2001 From: Ucanbarlic Date: Wed, 4 Sep 2024 08:56:09 +0200 Subject: [PATCH 3/3] Add unit tests for empty and truncated ByteBuffer description --- Tests/NIOCoreTests/ByteBufferTest.swift | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/Tests/NIOCoreTests/ByteBufferTest.swift b/Tests/NIOCoreTests/ByteBufferTest.swift index 29a5af1a16..78f4ff8023 100644 --- a/Tests/NIOCoreTests/ByteBufferTest.swift +++ b/Tests/NIOCoreTests/ByteBufferTest.swift @@ -3615,4 +3615,25 @@ extension ByteBufferTest { XCTAssertEqual(buffer.description, buffer.debugDescription) } + + func testByteBufferDescriptionEmpty() { + let buffer = ByteBuffer() + + XCTAssertEqual(buffer.description, "[](0 bytes)") + + XCTAssertEqual(buffer.description, buffer.debugDescription) + } + + func testByteBufferDescriptionTruncated() { + let buffer = ByteBuffer( + string: "iloveswiftnioiloveswiftnioiloveswiftnioiloveswiftnioiloveswiftnioiloveswiftnio" + ) + + XCTAssertEqual( + buffer.description, + "[696c6f766573776966746e696f696c6f766573776966746e696f696c6f766573...6966746e696f696c6f766573776966746e696f696c6f766573776966746e696f](78 bytes)" + ) + + XCTAssertEqual(buffer.description, buffer.debugDescription) + } }