Browse Source

Adopt swift-testing for Timeout tests (#2051)

Motivation:

swift-testing has a number of advantages over XCTest (parameterisation,
organisation, failure messages etc.), we should start using it instead
of XCTest.

Modifications:

- Convert the Timeout tests

Results:

Better tests
George Barnett 1 year ago
parent
commit
c51784ed35
1 changed files with 64 additions and 185 deletions
  1. 64 185
      Tests/GRPCCoreTests/TimeoutTests.swift

+ 64 - 185
Tests/GRPCCoreTests/TimeoutTests.swift

@@ -13,193 +13,72 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-import XCTest
 
-@testable import GRPCCore
-
-@available(macOS 13, iOS 16, tvOS 16, watchOS 9, *)
-final class TimeoutTests: XCTestCase {
-  func testDecodeInvalidTimeout_Empty() {
-    let timeoutHeader = ""
-    XCTAssertNil(Timeout(decoding: timeoutHeader))
-  }
-
-  func testDecodeInvalidTimeout_NoAmount() {
-    let timeoutHeader = "H"
-    XCTAssertNil(Timeout(decoding: timeoutHeader))
-  }
-
-  func testDecodeInvalidTimeout_NoUnit() {
-    let timeoutHeader = "123"
-    XCTAssertNil(Timeout(decoding: timeoutHeader))
-  }
-
-  func testDecodeInvalidTimeout_TooLongAmount() {
-    let timeoutHeader = "100000000S"
-    XCTAssertNil(Timeout(decoding: timeoutHeader))
-  }
-
-  func testDecodeInvalidTimeout_InvalidUnit() {
-    let timeoutHeader = "123j"
-    XCTAssertNil(Timeout(decoding: timeoutHeader))
-  }
-
-  func testDecodeValidTimeout_Hours() throws {
-    let timeoutHeader = "123H"
-    let timeout = Timeout(decoding: timeoutHeader)
-    let unwrappedTimeout = try XCTUnwrap(timeout)
-    XCTAssertEqual(unwrappedTimeout.duration, Duration.hours(123))
-    XCTAssertEqual(unwrappedTimeout.wireEncoding, timeoutHeader)
-  }
-
-  func testDecodeValidTimeout_Minutes() throws {
-    let timeoutHeader = "123M"
-    let timeout = Timeout(decoding: timeoutHeader)
-    let unwrappedTimeout = try XCTUnwrap(timeout)
-    XCTAssertEqual(unwrappedTimeout.duration, Duration.minutes(123))
-    XCTAssertEqual(unwrappedTimeout.wireEncoding, timeoutHeader)
-  }
-
-  func testDecodeValidTimeout_Seconds() throws {
-    let timeoutHeader = "123S"
-    let timeout = Timeout(decoding: timeoutHeader)
-    let unwrappedTimeout = try XCTUnwrap(timeout)
-    XCTAssertEqual(unwrappedTimeout.duration, Duration.seconds(123))
-    XCTAssertEqual(unwrappedTimeout.wireEncoding, timeoutHeader)
-  }
-
-  func testDecodeValidTimeout_Milliseconds() throws {
-    let timeoutHeader = "123m"
-    let timeout = Timeout(decoding: timeoutHeader)
-    let unwrappedTimeout = try XCTUnwrap(timeout)
-    XCTAssertEqual(unwrappedTimeout.duration, Duration.milliseconds(123))
-    XCTAssertEqual(unwrappedTimeout.wireEncoding, timeoutHeader)
-  }
-
-  func testDecodeValidTimeout_Microseconds() throws {
-    let timeoutHeader = "123u"
-    let timeout = Timeout(decoding: timeoutHeader)
-    let unwrappedTimeout = try XCTUnwrap(timeout)
-    XCTAssertEqual(unwrappedTimeout.duration, Duration.microseconds(123))
-    XCTAssertEqual(unwrappedTimeout.wireEncoding, timeoutHeader)
-  }
-
-  func testDecodeValidTimeout_Nanoseconds() throws {
-    let timeoutHeader = "123n"
-    let timeout = Timeout(decoding: timeoutHeader)
-    let unwrappedTimeout = try XCTUnwrap(timeout)
-    XCTAssertEqual(unwrappedTimeout.duration, Duration.nanoseconds(123))
-    XCTAssertEqual(unwrappedTimeout.wireEncoding, timeoutHeader)
-  }
+import Testing
 
-  func testEncodeValidTimeout_Hours() {
-    let duration = Duration.hours(123)
-    let timeout = Timeout(duration: duration)
-    XCTAssertEqual(timeout.duration.components.seconds, duration.components.seconds)
-    XCTAssertEqual(timeout.duration.components.attoseconds, duration.components.attoseconds)
-  }
-
-  func testEncodeValidTimeout_Minutes() {
-    let duration = Duration.minutes(43)
-    let timeout = Timeout(duration: duration)
-    XCTAssertEqual(timeout.duration.components.seconds, duration.components.seconds)
-    XCTAssertEqual(timeout.duration.components.attoseconds, duration.components.attoseconds)
-  }
-
-  func testEncodeValidTimeout_Seconds() {
-    let duration = Duration.seconds(12345)
-    let timeout = Timeout(duration: duration)
-    XCTAssertEqual(timeout.duration.components.seconds, duration.components.seconds)
-    XCTAssertEqual(timeout.duration.components.attoseconds, duration.components.attoseconds)
-  }
-
-  func testEncodeValidTimeout_Seconds_TooLong_Minutes() {
-    let duration = Duration.seconds(111_111_111)
-    let timeout = Timeout(duration: duration)
-    // The conversion from seconds to minutes results in a loss of precision.
-    // 111,111,111 seconds / 60 = 1,851,851.85 minutes -rounding up-> 1,851,852 minutes * 60 = 111,111,120 seconds
-    let expectedRoundedDuration = Duration.minutes(1_851_852)
-    XCTAssertEqual(timeout.duration.components.seconds, expectedRoundedDuration.components.seconds)
-    XCTAssertEqual(
-      timeout.duration.components.attoseconds,
-      expectedRoundedDuration.components.attoseconds
-    )
-  }
-
-  func testEncodeValidTimeout_Seconds_TooLong_Hours() {
-    let duration = Duration.seconds(9_999_999_999 as Int64)
-    let timeout = Timeout(duration: duration)
-    // The conversion from seconds to hours results in a loss of precision.
-    // 9,999,999,999 seconds / 60 = 166,666,666.65 minutes -rounding up->
-    // 166,666,667 minutes / 60 = 2,777,777.78 hours -rounding up->
-    // 2,777,778 hours * 60 -> 166,666,680 minutes * 60 = 10,000,000,800 seconds
-    let expectedRoundedDuration = Duration.hours(2_777_778)
-    XCTAssertEqual(timeout.duration.components.seconds, expectedRoundedDuration.components.seconds)
-    XCTAssertEqual(
-      timeout.duration.components.attoseconds,
-      expectedRoundedDuration.components.attoseconds
-    )
-  }
-
-  func testEncodeValidTimeout_Seconds_TooLong_MaxAmount() {
-    let duration = Duration.seconds(999_999_999_999 as Int64)
-    let timeout = Timeout(duration: duration)
-    // The conversion from seconds to hours results in a number that still has
-    // more than the maximum allowed 8 digits, so we must clamp it.
-    // Make sure that `Timeout.maxAmount` is the amount used for the resulting timeout.
-    let expectedRoundedDuration = Duration.hours(Timeout.maxAmount)
-    XCTAssertEqual(timeout.duration.components.seconds, expectedRoundedDuration.components.seconds)
-    XCTAssertEqual(
-      timeout.duration.components.attoseconds,
-      expectedRoundedDuration.components.attoseconds
-    )
-  }
-
-  func testEncodeValidTimeout_SecondsAndMilliseconds() {
-    let duration = Duration(secondsComponent: 100, attosecondsComponent: Int64(1e+17))
-    let timeout = Timeout(duration: duration)
-    XCTAssertEqual(timeout.duration.components.seconds, duration.components.seconds)
-    XCTAssertEqual(timeout.duration.components.attoseconds, duration.components.attoseconds)
-  }
-
-  func testEncodeValidTimeout_SecondsAndMicroseconds() {
-    let duration = Duration(secondsComponent: 1, attosecondsComponent: Int64(1e+14))
-    let timeout = Timeout(duration: duration)
-    XCTAssertEqual(timeout.duration.components.seconds, duration.components.seconds)
-    XCTAssertEqual(timeout.duration.components.attoseconds, duration.components.attoseconds)
-  }
-
-  func testEncodeValidTimeout_SecondsAndNanoseconds() {
-    let duration = Duration(secondsComponent: 1, attosecondsComponent: Int64(1e+11))
-    let timeout = Timeout(duration: duration)
-    // We can't convert seconds to nanoseconds because that would require at least
-    // 9 digits, and the maximum allowed is 8: we expect to simply drop the nanoseconds.
-    let expectedRoundedDuration = Duration.seconds(1)
-    XCTAssertEqual(timeout.duration.components.seconds, expectedRoundedDuration.components.seconds)
-    XCTAssertEqual(
-      timeout.duration.components.attoseconds,
-      expectedRoundedDuration.components.attoseconds
-    )
-  }
-
-  func testEncodeValidTimeout_Milliseconds() {
-    let duration = Duration.milliseconds(100)
-    let timeout = Timeout(duration: duration)
-    XCTAssertEqual(timeout.duration.components.seconds, duration.components.seconds)
-    XCTAssertEqual(timeout.duration.components.attoseconds, duration.components.attoseconds)
-  }
-
-  func testEncodeValidTimeout_Microseconds() {
-    let duration = Duration.microseconds(100)
-    let timeout = Timeout(duration: duration)
-    XCTAssertEqual(timeout.duration.components.seconds, duration.components.seconds)
-    XCTAssertEqual(timeout.duration.components.attoseconds, duration.components.attoseconds)
-  }
+@testable import GRPCCore
 
-  func testEncodeValidTimeout_Nanoseconds() {
-    let duration = Duration.nanoseconds(100)
-    let timeout = Timeout(duration: duration)
-    XCTAssertEqual(timeout.duration.components.seconds, duration.components.seconds)
-    XCTAssertEqual(timeout.duration.components.attoseconds, duration.components.attoseconds)
+struct TimeoutTests {
+  @Test("Initialize from invalid String value", arguments: ["", "H", "123", "100000000S", "123j"])
+  func initFromStringWithInvalidValue(_ value: String) throws {
+    #expect(Timeout(decoding: value) == nil)
+  }
+
+  @Test(
+    "Initialize from String",
+    arguments: [
+      ("123H", .hours(123)),
+      ("123M", .minutes(123)),
+      ("123S", .seconds(123)),
+      ("123m", .milliseconds(123)),
+      ("123u", .microseconds(123)),
+      ("123n", .nanoseconds(123)),
+    ] as [(String, Duration)]
+  )
+  func initFromString(_ value: String, expected: Duration) throws {
+    let timeout = try #require(Timeout(decoding: value))
+    #expect(timeout.duration == expected)
+  }
+
+  @Test(
+    "Initialize from Duration",
+    arguments: [
+      .hours(123),
+      .minutes(43),
+      .seconds(12345),
+      .milliseconds(100),
+      .microseconds(100),
+      .nanoseconds(100),
+    ] as [Duration]
+  )
+  func initFromDuration(_ value: Duration) {
+    let timeout = Timeout(duration: value)
+    #expect(timeout.duration == value)
+  }
+
+  @Test(
+    "Initialize from Duration with loss of precision",
+    arguments: [
+      // 111,111,111 seconds / 60 = 1,851,851.85 minutes -rounding up-> 1,851,852 minutes * 60 = 111,111,120 seconds
+      (.seconds(111_111_111), .minutes(1_851_852)),
+
+      // 9,999,999,999 seconds / 60 = 166,666,666.65 minutes -rounding up->
+      // 166,666,667 minutes / 60 = 2,777,777.78 hours -rounding up->
+      // 2,777,778 hours * 60 -> 166,666,680 minutes * 60 = 10,000,000,800 seconds
+      (.seconds(9_999_999_999 as Int64), .hours(2_777_778)),
+
+      // The conversion from seconds to hours results in a number that still has
+      // more than the maximum allowed 8 digits, so we must clamp it.
+      // Make sure that `Timeout.maxAmount` is the amount used for the resulting timeout.
+      (.seconds(999_999_999_999 as Int64), .hours(Timeout.maxAmount)),
+
+      // We can't convert seconds to nanoseconds because that would require at least
+      // 9 digits, and the maximum allowed is 8: we expect to simply drop the nanoseconds.
+      (Duration(secondsComponent: 1, attosecondsComponent: Int64(1e11)), .seconds(1)),
+    ] as [(Duration, Duration)]
+  )
+  func initFromDurationWithLossOfPrecision(original: Duration, rounded: Duration) {
+    let timeout = Timeout(duration: original)
+    #expect(timeout.duration == rounded)
   }
 }