RLMAssertions.h 6.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108
  1. ////////////////////////////////////////////////////////////////////////////
  2. //
  3. // Copyright 2015 Realm Inc.
  4. //
  5. // Licensed under the Apache License, Version 2.0 (the "License");
  6. // you may not use this file except in compliance with the License.
  7. // You may obtain a copy of the License at
  8. //
  9. // http://www.apache.org/licenses/LICENSE-2.0
  10. //
  11. // Unless required by applicable law or agreed to in writing, software
  12. // distributed under the License is distributed on an "AS IS" BASIS,
  13. // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  14. // See the License for the specific language governing permissions and
  15. // limitations under the License.
  16. //
  17. ////////////////////////////////////////////////////////////////////////////
  18. #import <XCTest/XCTest.h>
  19. #define RLMAssertThrows(expression, ...) \
  20. RLMPrimitiveAssertThrows(self, expression, __VA_ARGS__)
  21. #define RLMPrimitiveAssertThrows(self, expression, format...) \
  22. ({ \
  23. NSException *caughtException = nil; \
  24. @try { \
  25. (expression); \
  26. } \
  27. @catch (id exception) { \
  28. caughtException = exception; \
  29. } \
  30. if (!caughtException) { \
  31. _XCTRegisterFailure(self, _XCTFailureDescription(_XCTAssertion_Throws, 0, @#expression), format); \
  32. } \
  33. caughtException; \
  34. })
  35. #define RLMAssertMatches(expression, regex, ...) \
  36. RLMPrimitiveAssertMatches(self, expression, regex, __VA_ARGS__)
  37. #define RLMPrimitiveAssertMatches(self, expression, regexString, format...) \
  38. ({ \
  39. NSString *string = (expression); \
  40. NSRegularExpression *regex = [NSRegularExpression regularExpressionWithPattern:regexString options:(NSRegularExpressionOptions)0 error:nil]; \
  41. if ([regex numberOfMatchesInString:string options:(NSMatchingOptions)0 range:NSMakeRange(0, string.length)] == 0) { \
  42. _XCTRegisterFailure(self, [_XCTFailureDescription(_XCTAssertion_True, 0, @#expression @" (EXPR_STRING) matches " @#regexString) stringByReplacingOccurrencesOfString:@"EXPR_STRING" withString:string ?: @"<nil>"], format); \
  43. } \
  44. })
  45. #define RLMAssertThrowsWithReasonMatching(expression, regex, ...) \
  46. ({ \
  47. NSException *exception = RLMAssertThrows(expression, __VA_ARGS__); \
  48. if (exception) { \
  49. RLMAssertMatches(exception.reason, regex, __VA_ARGS__); \
  50. } \
  51. exception; \
  52. })
  53. #define RLMAssertThrowsWithReason(expression, expected, ...) \
  54. ({ \
  55. NSException *exception = RLMAssertThrows(expression); \
  56. if (exception) { \
  57. if ([exception.reason rangeOfString:(expected)].location == NSNotFound) { \
  58. _XCTRegisterFailure(self, \
  59. [_XCTFailureDescription(_XCTAssertion_True, 0, @#expression " (EXPR_STRING) contains " #expected) \
  60. stringByReplacingOccurrencesOfString:@"EXPR_STRING" \
  61. withString:exception.reason ?: @"<nil>"]); \
  62. } \
  63. } \
  64. exception; \
  65. })
  66. #define RLMAssertThrowsWithCodeMatching(expression, expectedCode, ...) \
  67. ({ \
  68. NSException *exception = RLMAssertThrows(expression, __VA_ARGS__); \
  69. XCTAssertEqual([exception.userInfo[NSUnderlyingErrorKey] code], expectedCode, __VA_ARGS__); \
  70. })
  71. #define RLMValidateRealmError(macro_error, macro_errnum, macro_description, macro_underlying) \
  72. ({ \
  73. NSString *macro_dsc = macro_description; \
  74. NSString *macro_usl = macro_underlying; \
  75. macro_dsc = [macro_dsc lowercaseString]; \
  76. macro_usl = [macro_usl lowercaseString]; \
  77. NSError *macro_castErr = (NSError *)macro_error; \
  78. XCTAssertNotNil(macro_castErr); \
  79. XCTAssertEqual(macro_castErr.domain, RLMErrorDomain, @"Was expecting the error domain '%@', but got non-interned '%@' instead", RLMErrorDomain, macro_castErr.domain); \
  80. XCTAssertEqual(macro_castErr.code, macro_errnum); \
  81. if (macro_dsc.length) { \
  82. NSString *macro_dscActual = [macro_castErr.userInfo[NSLocalizedDescriptionKey] lowercaseString]; \
  83. XCTAssertNotNil(macro_dscActual); \
  84. XCTAssert([macro_dscActual rangeOfString:macro_dsc].location != NSNotFound, @"Did not find the expected string '%@' in the description string '%@'", macro_dsc, macro_dscActual); \
  85. } \
  86. if (macro_usl.length) { \
  87. NSString *macro_uslActual = [macro_castErr.userInfo[@"Underlying"] lowercaseString]; \
  88. XCTAssertNotNil(macro_uslActual); \
  89. XCTAssert([macro_uslActual rangeOfString:macro_usl].location != NSNotFound, @"Did not find the expected string '%@' in the underlying info string '%@'", macro_usl, macro_uslActual); \
  90. } \
  91. })
  92. /// Check that an exception is thrown, and validate additional details about its underlying error.
  93. #define RLMAssertThrowsWithError(macro_expr, macro_except_string, macro_errnum, macro_underlying_string) \
  94. ({ \
  95. NSException *macro_exception = RLMAssertThrowsWithReasonMatching(macro_expr, macro_except_string); \
  96. NSError *macro_excErr = (NSError *)(macro_exception.userInfo[NSUnderlyingErrorKey]); \
  97. RLMValidateRealmError(macro_excErr, macro_errnum, nil, macro_underlying_string); \
  98. })