DSL.h 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389
  1. #import <Foundation/Foundation.h>
  2. @class NMBExpectation;
  3. @class NMBObjCBeCloseToMatcher;
  4. @class NMBObjCRaiseExceptionMatcher;
  5. @protocol NMBMatcher;
  6. NS_ASSUME_NONNULL_BEGIN
  7. #define NIMBLE_OVERLOADABLE __attribute__((overloadable))
  8. #define NIMBLE_EXPORT FOUNDATION_EXPORT
  9. #define NIMBLE_EXPORT_INLINE FOUNDATION_STATIC_INLINE
  10. #define NIMBLE_VALUE_OF(VAL) ({ \
  11. __typeof__((VAL)) val = (VAL); \
  12. [NSValue valueWithBytes:&val objCType:@encode(__typeof__((VAL)))]; \
  13. })
  14. #ifdef NIMBLE_DISABLE_SHORT_SYNTAX
  15. #define NIMBLE_SHORT(PROTO, ORIGINAL)
  16. #define NIMBLE_SHORT_OVERLOADED(PROTO, ORIGINAL)
  17. #else
  18. #define NIMBLE_SHORT(PROTO, ORIGINAL) FOUNDATION_STATIC_INLINE PROTO { return (ORIGINAL); }
  19. #define NIMBLE_SHORT_OVERLOADED(PROTO, ORIGINAL) FOUNDATION_STATIC_INLINE NIMBLE_OVERLOADABLE PROTO { return (ORIGINAL); }
  20. #endif
  21. #define DEFINE_NMB_EXPECT_OVERLOAD(TYPE, EXPR) \
  22. NIMBLE_EXPORT_INLINE NIMBLE_OVERLOADABLE \
  23. NMBExpectation *NMB_expect(TYPE(^actualBlock)(void), NSString *file, NSUInteger line) { \
  24. return NMB_expect(^id { return EXPR; }, file, line); \
  25. }
  26. NIMBLE_EXPORT NIMBLE_OVERLOADABLE
  27. NMBExpectation *NMB_expect(id(^actualBlock)(void), NSString *file, NSUInteger line);
  28. // overloaded dispatch for nils - expect(nil)
  29. DEFINE_NMB_EXPECT_OVERLOAD(void*, nil)
  30. DEFINE_NMB_EXPECT_OVERLOAD(NSRange, NIMBLE_VALUE_OF(actualBlock()))
  31. DEFINE_NMB_EXPECT_OVERLOAD(long, @(actualBlock()))
  32. DEFINE_NMB_EXPECT_OVERLOAD(unsigned long, @(actualBlock()))
  33. DEFINE_NMB_EXPECT_OVERLOAD(int, @(actualBlock()))
  34. DEFINE_NMB_EXPECT_OVERLOAD(unsigned int, @(actualBlock()))
  35. DEFINE_NMB_EXPECT_OVERLOAD(float, @(actualBlock()))
  36. DEFINE_NMB_EXPECT_OVERLOAD(double, @(actualBlock()))
  37. DEFINE_NMB_EXPECT_OVERLOAD(long long, @(actualBlock()))
  38. DEFINE_NMB_EXPECT_OVERLOAD(unsigned long long, @(actualBlock()))
  39. DEFINE_NMB_EXPECT_OVERLOAD(char, @(actualBlock()))
  40. DEFINE_NMB_EXPECT_OVERLOAD(unsigned char, @(actualBlock()))
  41. // bool doesn't get the compiler to dispatch to BOOL types, but using BOOL here seems to allow
  42. // the compiler to dispatch to bool.
  43. DEFINE_NMB_EXPECT_OVERLOAD(BOOL, @(actualBlock()))
  44. DEFINE_NMB_EXPECT_OVERLOAD(char *, @(actualBlock()))
  45. #undef DEFINE_NMB_EXPECT_OVERLOAD
  46. NIMBLE_EXPORT NMBExpectation *NMB_expectAction(void(^actualBlock)(void), NSString *file, NSUInteger line);
  47. #define DEFINE_OVERLOAD(TYPE, EXPR) \
  48. NIMBLE_EXPORT_INLINE NIMBLE_OVERLOADABLE \
  49. id<NMBMatcher> NMB_equal(TYPE expectedValue) { \
  50. return NMB_equal((EXPR)); \
  51. } \
  52. NIMBLE_SHORT_OVERLOADED(id<NMBMatcher> equal(TYPE expectedValue), NMB_equal(expectedValue));
  53. NIMBLE_EXPORT NIMBLE_OVERLOADABLE
  54. id<NMBMatcher> NMB_equal(__nullable id expectedValue);
  55. NIMBLE_SHORT_OVERLOADED(id<NMBMatcher> equal(__nullable id expectedValue),
  56. NMB_equal(expectedValue));
  57. // overloaded dispatch for nils - expect(nil)
  58. DEFINE_OVERLOAD(void*__nullable, (id)nil)
  59. DEFINE_OVERLOAD(NSRange, NIMBLE_VALUE_OF(expectedValue))
  60. DEFINE_OVERLOAD(long, @(expectedValue))
  61. DEFINE_OVERLOAD(unsigned long, @(expectedValue))
  62. DEFINE_OVERLOAD(int, @(expectedValue))
  63. DEFINE_OVERLOAD(unsigned int, @(expectedValue))
  64. DEFINE_OVERLOAD(float, @(expectedValue))
  65. DEFINE_OVERLOAD(double, @(expectedValue))
  66. DEFINE_OVERLOAD(long long, @(expectedValue))
  67. DEFINE_OVERLOAD(unsigned long long, @(expectedValue))
  68. DEFINE_OVERLOAD(char, @(expectedValue))
  69. DEFINE_OVERLOAD(unsigned char, @(expectedValue))
  70. // bool doesn't get the compiler to dispatch to BOOL types, but using BOOL here seems to allow
  71. // the compiler to dispatch to bool.
  72. DEFINE_OVERLOAD(BOOL, @(expectedValue))
  73. DEFINE_OVERLOAD(char *, @(expectedValue))
  74. #undef DEFINE_OVERLOAD
  75. #define DEFINE_OVERLOAD(TYPE, EXPR) \
  76. NIMBLE_EXPORT_INLINE NIMBLE_OVERLOADABLE \
  77. id<NMBMatcher> NMB_haveCount(TYPE expectedValue) { \
  78. return NMB_haveCount((EXPR)); \
  79. } \
  80. NIMBLE_SHORT_OVERLOADED(id<NMBMatcher> haveCount(TYPE expectedValue), \
  81. NMB_haveCount(expectedValue));
  82. NIMBLE_EXPORT NIMBLE_OVERLOADABLE
  83. id<NMBMatcher> NMB_haveCount(id expectedValue);
  84. NIMBLE_SHORT_OVERLOADED(id<NMBMatcher> haveCount(id expectedValue),
  85. NMB_haveCount(expectedValue));
  86. DEFINE_OVERLOAD(long, @(expectedValue))
  87. DEFINE_OVERLOAD(unsigned long, @(expectedValue))
  88. DEFINE_OVERLOAD(int, @(expectedValue))
  89. DEFINE_OVERLOAD(unsigned int, @(expectedValue))
  90. DEFINE_OVERLOAD(long long, @(expectedValue))
  91. DEFINE_OVERLOAD(unsigned long long, @(expectedValue))
  92. DEFINE_OVERLOAD(char, @(expectedValue))
  93. DEFINE_OVERLOAD(unsigned char, @(expectedValue))
  94. #undef DEFINE_OVERLOAD
  95. #define DEFINE_OVERLOAD(TYPE, EXPR) \
  96. NIMBLE_EXPORT_INLINE NIMBLE_OVERLOADABLE \
  97. NMBObjCBeCloseToMatcher *NMB_beCloseTo(TYPE expectedValue) { \
  98. return NMB_beCloseTo((NSNumber *)(EXPR)); \
  99. } \
  100. NIMBLE_SHORT_OVERLOADED(NMBObjCBeCloseToMatcher *beCloseTo(TYPE expectedValue), \
  101. NMB_beCloseTo(expectedValue));
  102. NIMBLE_EXPORT NIMBLE_OVERLOADABLE NMBObjCBeCloseToMatcher *NMB_beCloseTo(NSNumber *expectedValue);
  103. NIMBLE_SHORT_OVERLOADED(NMBObjCBeCloseToMatcher *beCloseTo(NSNumber *expectedValue),
  104. NMB_beCloseTo(expectedValue));
  105. // it would be better to only overload float & double, but zero becomes ambigious
  106. DEFINE_OVERLOAD(long, @(expectedValue))
  107. DEFINE_OVERLOAD(unsigned long, @(expectedValue))
  108. DEFINE_OVERLOAD(int, @(expectedValue))
  109. DEFINE_OVERLOAD(unsigned int, @(expectedValue))
  110. DEFINE_OVERLOAD(float, @(expectedValue))
  111. DEFINE_OVERLOAD(double, @(expectedValue))
  112. DEFINE_OVERLOAD(long long, @(expectedValue))
  113. DEFINE_OVERLOAD(unsigned long long, @(expectedValue))
  114. DEFINE_OVERLOAD(char, @(expectedValue))
  115. DEFINE_OVERLOAD(unsigned char, @(expectedValue))
  116. #undef DEFINE_OVERLOAD
  117. NIMBLE_EXPORT id<NMBMatcher> NMB_beAnInstanceOf(Class expectedClass);
  118. NIMBLE_EXPORT_INLINE id<NMBMatcher> beAnInstanceOf(Class expectedClass) {
  119. return NMB_beAnInstanceOf(expectedClass);
  120. }
  121. NIMBLE_EXPORT id<NMBMatcher> NMB_beAKindOf(Class expectedClass);
  122. NIMBLE_EXPORT_INLINE id<NMBMatcher> beAKindOf(Class expectedClass) {
  123. return NMB_beAKindOf(expectedClass);
  124. }
  125. NIMBLE_EXPORT id<NMBMatcher> NMB_beginWith(id itemElementOrSubstring);
  126. NIMBLE_EXPORT_INLINE id<NMBMatcher> beginWith(id itemElementOrSubstring) {
  127. return NMB_beginWith(itemElementOrSubstring);
  128. }
  129. #define DEFINE_OVERLOAD(TYPE, EXPR) \
  130. NIMBLE_EXPORT_INLINE NIMBLE_OVERLOADABLE \
  131. id<NMBMatcher> NMB_beGreaterThan(TYPE expectedValue) { \
  132. return NMB_beGreaterThan((EXPR)); \
  133. } \
  134. NIMBLE_SHORT_OVERLOADED(id<NMBMatcher> beGreaterThan(TYPE expectedValue), NMB_beGreaterThan(expectedValue));
  135. NIMBLE_EXPORT NIMBLE_OVERLOADABLE
  136. id<NMBMatcher> NMB_beGreaterThan(NSNumber *expectedValue);
  137. NIMBLE_EXPORT_INLINE NIMBLE_OVERLOADABLE
  138. id<NMBMatcher> beGreaterThan(NSNumber *expectedValue) {
  139. return NMB_beGreaterThan(expectedValue);
  140. }
  141. DEFINE_OVERLOAD(long, @(expectedValue))
  142. DEFINE_OVERLOAD(unsigned long, @(expectedValue))
  143. DEFINE_OVERLOAD(int, @(expectedValue))
  144. DEFINE_OVERLOAD(unsigned int, @(expectedValue))
  145. DEFINE_OVERLOAD(float, @(expectedValue))
  146. DEFINE_OVERLOAD(double, @(expectedValue))
  147. DEFINE_OVERLOAD(long long, @(expectedValue))
  148. DEFINE_OVERLOAD(unsigned long long, @(expectedValue))
  149. DEFINE_OVERLOAD(char, @(expectedValue))
  150. DEFINE_OVERLOAD(unsigned char, @(expectedValue))
  151. #undef DEFINE_OVERLOAD
  152. #define DEFINE_OVERLOAD(TYPE, EXPR) \
  153. NIMBLE_EXPORT_INLINE NIMBLE_OVERLOADABLE \
  154. id<NMBMatcher> NMB_beGreaterThanOrEqualTo(TYPE expectedValue) { \
  155. return NMB_beGreaterThanOrEqualTo((EXPR)); \
  156. } \
  157. NIMBLE_SHORT_OVERLOADED(id<NMBMatcher> beGreaterThanOrEqualTo(TYPE expectedValue), \
  158. NMB_beGreaterThanOrEqualTo(expectedValue));
  159. NIMBLE_EXPORT NIMBLE_OVERLOADABLE
  160. id<NMBMatcher> NMB_beGreaterThanOrEqualTo(NSNumber *expectedValue);
  161. NIMBLE_EXPORT_INLINE NIMBLE_OVERLOADABLE
  162. id<NMBMatcher> beGreaterThanOrEqualTo(NSNumber *expectedValue) {
  163. return NMB_beGreaterThanOrEqualTo(expectedValue);
  164. }
  165. DEFINE_OVERLOAD(long, @(expectedValue))
  166. DEFINE_OVERLOAD(unsigned long, @(expectedValue))
  167. DEFINE_OVERLOAD(int, @(expectedValue))
  168. DEFINE_OVERLOAD(unsigned int, @(expectedValue))
  169. DEFINE_OVERLOAD(float, @(expectedValue))
  170. DEFINE_OVERLOAD(double, @(expectedValue))
  171. DEFINE_OVERLOAD(long long, @(expectedValue))
  172. DEFINE_OVERLOAD(unsigned long long, @(expectedValue))
  173. DEFINE_OVERLOAD(char, @(expectedValue))
  174. DEFINE_OVERLOAD(unsigned char, @(expectedValue))
  175. #undef DEFINE_OVERLOAD
  176. NIMBLE_EXPORT id<NMBMatcher> NMB_beIdenticalTo(id expectedInstance);
  177. NIMBLE_SHORT(id<NMBMatcher> beIdenticalTo(id expectedInstance),
  178. NMB_beIdenticalTo(expectedInstance));
  179. NIMBLE_EXPORT id<NMBMatcher> NMB_be(id expectedInstance);
  180. NIMBLE_SHORT(id<NMBMatcher> be(id expectedInstance),
  181. NMB_be(expectedInstance));
  182. #define DEFINE_OVERLOAD(TYPE, EXPR) \
  183. NIMBLE_EXPORT_INLINE NIMBLE_OVERLOADABLE \
  184. id<NMBMatcher> NMB_beLessThan(TYPE expectedValue) { \
  185. return NMB_beLessThan((EXPR)); \
  186. } \
  187. NIMBLE_SHORT_OVERLOADED(id<NMBMatcher> beLessThan(TYPE expectedValue), \
  188. NMB_beLessThan(expectedValue));
  189. NIMBLE_EXPORT NIMBLE_OVERLOADABLE
  190. id<NMBMatcher> NMB_beLessThan(NSNumber *expectedValue);
  191. NIMBLE_EXPORT_INLINE NIMBLE_OVERLOADABLE
  192. id<NMBMatcher> beLessThan(NSNumber *expectedValue) {
  193. return NMB_beLessThan(expectedValue);
  194. }
  195. DEFINE_OVERLOAD(long, @(expectedValue))
  196. DEFINE_OVERLOAD(unsigned long, @(expectedValue))
  197. DEFINE_OVERLOAD(int, @(expectedValue))
  198. DEFINE_OVERLOAD(unsigned int, @(expectedValue))
  199. DEFINE_OVERLOAD(float, @(expectedValue))
  200. DEFINE_OVERLOAD(double, @(expectedValue))
  201. DEFINE_OVERLOAD(long long, @(expectedValue))
  202. DEFINE_OVERLOAD(unsigned long long, @(expectedValue))
  203. DEFINE_OVERLOAD(char, @(expectedValue))
  204. DEFINE_OVERLOAD(unsigned char, @(expectedValue))
  205. #undef DEFINE_OVERLOAD
  206. #define DEFINE_OVERLOAD(TYPE, EXPR) \
  207. NIMBLE_EXPORT_INLINE NIMBLE_OVERLOADABLE \
  208. id<NMBMatcher> NMB_beLessThanOrEqualTo(TYPE expectedValue) { \
  209. return NMB_beLessThanOrEqualTo((EXPR)); \
  210. } \
  211. NIMBLE_SHORT_OVERLOADED(id<NMBMatcher> beLessThanOrEqualTo(TYPE expectedValue), \
  212. NMB_beLessThanOrEqualTo(expectedValue));
  213. NIMBLE_EXPORT NIMBLE_OVERLOADABLE
  214. id<NMBMatcher> NMB_beLessThanOrEqualTo(NSNumber *expectedValue);
  215. NIMBLE_EXPORT_INLINE NIMBLE_OVERLOADABLE
  216. id<NMBMatcher> beLessThanOrEqualTo(NSNumber *expectedValue) {
  217. return NMB_beLessThanOrEqualTo(expectedValue);
  218. }
  219. DEFINE_OVERLOAD(long, @(expectedValue))
  220. DEFINE_OVERLOAD(unsigned long, @(expectedValue))
  221. DEFINE_OVERLOAD(int, @(expectedValue))
  222. DEFINE_OVERLOAD(unsigned int, @(expectedValue))
  223. DEFINE_OVERLOAD(float, @(expectedValue))
  224. DEFINE_OVERLOAD(double, @(expectedValue))
  225. DEFINE_OVERLOAD(long long, @(expectedValue))
  226. DEFINE_OVERLOAD(unsigned long long, @(expectedValue))
  227. DEFINE_OVERLOAD(char, @(expectedValue))
  228. DEFINE_OVERLOAD(unsigned char, @(expectedValue))
  229. #undef DEFINE_OVERLOAD
  230. NIMBLE_EXPORT id<NMBMatcher> NMB_beTruthy(void);
  231. NIMBLE_SHORT(id<NMBMatcher> beTruthy(void),
  232. NMB_beTruthy());
  233. NIMBLE_EXPORT id<NMBMatcher> NMB_beFalsy(void);
  234. NIMBLE_SHORT(id<NMBMatcher> beFalsy(void),
  235. NMB_beFalsy());
  236. NIMBLE_EXPORT id<NMBMatcher> NMB_beTrue(void);
  237. NIMBLE_SHORT(id<NMBMatcher> beTrue(void),
  238. NMB_beTrue());
  239. NIMBLE_EXPORT id<NMBMatcher> NMB_beFalse(void);
  240. NIMBLE_SHORT(id<NMBMatcher> beFalse(void),
  241. NMB_beFalse());
  242. NIMBLE_EXPORT id<NMBMatcher> NMB_beNil(void);
  243. NIMBLE_SHORT(id<NMBMatcher> beNil(void),
  244. NMB_beNil());
  245. NIMBLE_EXPORT id<NMBMatcher> NMB_beEmpty(void);
  246. NIMBLE_SHORT(id<NMBMatcher> beEmpty(void),
  247. NMB_beEmpty());
  248. NIMBLE_EXPORT id<NMBMatcher> NMB_containWithNilTermination(id itemOrSubstring, ...) NS_REQUIRES_NIL_TERMINATION;
  249. #define NMB_contain(...) NMB_containWithNilTermination(__VA_ARGS__, nil)
  250. #ifndef NIMBLE_DISABLE_SHORT_SYNTAX
  251. #define contain(...) NMB_contain(__VA_ARGS__)
  252. #endif
  253. NIMBLE_EXPORT id<NMBMatcher> NMB_containElementSatisfying(BOOL(^predicate)(id));
  254. NIMBLE_SHORT(id<NMBMatcher> containElementSatisfying(BOOL(^predicate)(id)),
  255. NMB_containElementSatisfying(predicate));
  256. NIMBLE_EXPORT id<NMBMatcher> NMB_endWith(id itemElementOrSubstring);
  257. NIMBLE_SHORT(id<NMBMatcher> endWith(id itemElementOrSubstring),
  258. NMB_endWith(itemElementOrSubstring));
  259. NIMBLE_EXPORT NMBObjCRaiseExceptionMatcher *NMB_raiseException(void);
  260. NIMBLE_SHORT(NMBObjCRaiseExceptionMatcher *raiseException(void),
  261. NMB_raiseException());
  262. NIMBLE_EXPORT id<NMBMatcher> NMB_match(id expectedValue);
  263. NIMBLE_SHORT(id<NMBMatcher> match(id expectedValue),
  264. NMB_match(expectedValue));
  265. NIMBLE_EXPORT id<NMBMatcher> NMB_allPass(id matcher);
  266. NIMBLE_SHORT(id<NMBMatcher> allPass(id matcher),
  267. NMB_allPass(matcher));
  268. NIMBLE_EXPORT id<NMBMatcher> NMB_satisfyAnyOfWithMatchers(id matchers);
  269. #define NMB_satisfyAnyOf(...) NMB_satisfyAnyOfWithMatchers(@[__VA_ARGS__])
  270. #ifndef NIMBLE_DISABLE_SHORT_SYNTAX
  271. #define satisfyAnyOf(...) NMB_satisfyAnyOf(__VA_ARGS__)
  272. #endif
  273. NIMBLE_EXPORT id<NMBMatcher> NMB_satisfyAllOfWithMatchers(id matchers);
  274. #define NMB_satisfyAllOf(...) NMB_satisfyAllOfWithMatchers(@[__VA_ARGS__])
  275. #ifndef NIMBLE_DISABLE_SHORT_SYNTAX
  276. #define satisfyAllOf(...) NMB_satisfyAllOf(__VA_ARGS__)
  277. #endif
  278. // In order to preserve breakpoint behavior despite using macros to fill in __FILE__ and __LINE__,
  279. // define a builder that populates __FILE__ and __LINE__, and returns a block that takes timeout
  280. // and action arguments. See https://github.com/Quick/Quick/pull/185 for details.
  281. typedef void (^NMBWaitUntilTimeoutBlock)(NSTimeInterval timeout, void (^action)(void (^)(void)));
  282. typedef void (^NMBWaitUntilBlock)(void (^action)(void (^)(void)));
  283. NIMBLE_EXPORT void NMB_failWithMessage(NSString *msg, NSString *file, NSUInteger line);
  284. NIMBLE_EXPORT NMBWaitUntilTimeoutBlock NMB_waitUntilTimeoutBuilder(NSString *file, NSUInteger line);
  285. NIMBLE_EXPORT NMBWaitUntilBlock NMB_waitUntilBuilder(NSString *file, NSUInteger line);
  286. NIMBLE_EXPORT void NMB_failWithMessage(NSString *msg, NSString *file, NSUInteger line);
  287. #define NMB_waitUntilTimeout NMB_waitUntilTimeoutBuilder(@(__FILE__), __LINE__)
  288. #define NMB_waitUntil NMB_waitUntilBuilder(@(__FILE__), __LINE__)
  289. #ifndef NIMBLE_DISABLE_SHORT_SYNTAX
  290. #define expect(...) NMB_expect(^{ return (__VA_ARGS__); }, @(__FILE__), __LINE__)
  291. #define expectAction(BLOCK) NMB_expectAction((BLOCK), @(__FILE__), __LINE__)
  292. #define failWithMessage(msg) NMB_failWithMessage(msg, @(__FILE__), __LINE__)
  293. #define fail() failWithMessage(@"fail() always fails")
  294. #define waitUntilTimeout NMB_waitUntilTimeout
  295. #define waitUntil NMB_waitUntil
  296. #undef NIMBLE_VALUE_OF
  297. #endif
  298. NS_ASSUME_NONNULL_END