ResultTests.swift 3.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143
  1. // Copyright (c) 2015 Rob Rix. All rights reserved.
  2. final class ResultTests: XCTestCase {
  3. func testMapTransformsSuccesses() {
  4. XCTAssertEqual(success.map { $0.characters.count } ?? 0, 7)
  5. }
  6. func testMapRewrapsFailures() {
  7. XCTAssertEqual(failure.map { $0.characters.count } ?? 0, 0)
  8. }
  9. func testInitOptionalSuccess() {
  10. XCTAssert(Result("success" as String?, failWith: error) == success)
  11. }
  12. func testInitOptionalFailure() {
  13. XCTAssert(Result(nil, failWith: error) == failure)
  14. }
  15. // MARK: Errors
  16. func testErrorsIncludeTheSourceFile() {
  17. let file = __FILE__
  18. XCTAssert(Result<(), NSError>.error().file == file)
  19. }
  20. func testErrorsIncludeTheSourceLine() {
  21. let (line, error) = (__LINE__, Result<(), NSError>.error())
  22. XCTAssertEqual(error.line ?? -1, line)
  23. }
  24. func testErrorsIncludeTheCallingFunction() {
  25. let function = __FUNCTION__
  26. XCTAssert(Result<(), NSError>.error().function == function)
  27. }
  28. // MARK: Try - Catch
  29. func testTryCatchProducesSuccesses() {
  30. let result: Result<String, NSError> = Result(try tryIsSuccess("success"))
  31. XCTAssert(result == success)
  32. }
  33. func testTryCatchProducesFailures() {
  34. let result: Result<String, NSError> = Result(try tryIsSuccess(nil))
  35. XCTAssert(result.error == error)
  36. }
  37. // MARK: Cocoa API idioms
  38. func testTryProducesFailuresForBooleanAPIWithErrorReturnedByReference() {
  39. let result = `try` { attempt(true, succeed: false, error: $0) }
  40. XCTAssertFalse(result ?? false)
  41. XCTAssertNotNil(result.error)
  42. }
  43. func testTryProducesFailuresForOptionalWithErrorReturnedByReference() {
  44. let result = `try` { attempt(1, succeed: false, error: $0) }
  45. XCTAssertEqual(result ?? 0, 0)
  46. XCTAssertNotNil(result.error)
  47. }
  48. func testTryProducesSuccessesForBooleanAPI() {
  49. let result = `try` { attempt(true, succeed: true, error: $0) }
  50. XCTAssertTrue(result ?? false)
  51. XCTAssertNil(result.error)
  52. }
  53. func testTryProducesSuccessesForOptionalAPI() {
  54. let result = `try` { attempt(1, succeed: true, error: $0) }
  55. XCTAssertEqual(result ?? 0, 1)
  56. XCTAssertNil(result.error)
  57. }
  58. // MARK: Operators
  59. func testConjunctionOperator() {
  60. let resultSuccess = success &&& success
  61. if let (x, y) = resultSuccess.value {
  62. XCTAssertTrue(x == "success" && y == "success")
  63. } else {
  64. XCTFail()
  65. }
  66. let resultFailureBoth = failure &&& failure2
  67. XCTAssert(resultFailureBoth.error == error)
  68. let resultFailureLeft = failure &&& success
  69. XCTAssert(resultFailureLeft.error == error)
  70. let resultFailureRight = success &&& failure2
  71. XCTAssert(resultFailureRight.error == error2)
  72. }
  73. }
  74. // MARK: - Fixtures
  75. let success = Result<String, NSError>.Success("success")
  76. let error = NSError(domain: "com.antitypical.Result", code: 0xdeadbeef, userInfo: nil)
  77. let error2 = NSError(domain: "com.antitypical.Result", code: 0x12345678, userInfo: nil)
  78. let failure = Result<String, NSError>.Failure(error)
  79. let failure2 = Result<String, NSError>.Failure(error2)
  80. // MARK: - Helpers
  81. func attempt<T>(value: T, succeed: Bool, error: NSErrorPointer) -> T? {
  82. if succeed {
  83. return value
  84. } else {
  85. error.memory = Result<(), NSError>.error()
  86. return nil
  87. }
  88. }
  89. func tryIsSuccess(text: String?) throws -> String {
  90. guard let text = text else {
  91. throw error
  92. }
  93. return text
  94. }
  95. extension NSError {
  96. var function: String? {
  97. return userInfo[Result<(), NSError>.functionKey as NSString] as? String
  98. }
  99. var file: String? {
  100. return userInfo[Result<(), NSError>.fileKey as NSString] as? String
  101. }
  102. var line: Int? {
  103. return userInfo[Result<(), NSError>.lineKey as NSString] as? Int
  104. }
  105. }
  106. import Result
  107. import XCTest