/MapView/GTM/GTMNSObject+UnitTesting.h

http://github.com/route-me/route-me · C Header · 427 lines · 83 code · 35 blank · 309 comment · 11 complexity · 870a864b1fa718aa6f60a534a0286846 MD5 · raw file

  1. //
  2. // GTMNSObject+UnitTesting.h
  3. //
  4. // Utilities for doing advanced unittesting with objects.
  5. //
  6. // Copyright 2006-2008 Google Inc.
  7. //
  8. // Licensed under the Apache License, Version 2.0 (the "License"); you may not
  9. // use this file except in compliance with the License. You may obtain a copy
  10. // of the License at
  11. //
  12. // http://www.apache.org/licenses/LICENSE-2.0
  13. //
  14. // Unless required by applicable law or agreed to in writing, software
  15. // distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
  16. // WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
  17. // License for the specific language governing permissions and limitations under
  18. // the License.
  19. //
  20. #import "GTMDefines.h"
  21. #import <Foundation/Foundation.h>
  22. #if GTM_MACOS_SDK
  23. #import <ApplicationServices/ApplicationServices.h>
  24. #elif GTM_IPHONE_SDK
  25. #import <CoreGraphics/CoreGraphics.h>
  26. #endif
  27. #import "GTMSenTestCase.h"
  28. // Utility functions for GTMAssert* Macros. Don't use them directly
  29. // but use the macros below instead
  30. BOOL GTMIsObjectImageEqualToImageNamed(id object,
  31. NSString *filename,
  32. NSString **error);
  33. BOOL GTMIsObjectStateEqualToStateNamed(id object,
  34. NSString *filename,
  35. NSString **error);
  36. // Fails when image of |a1| does not equal image in image file named |a2|
  37. //
  38. // Generates a failure when the unittest image of |a1| is not equal to the
  39. // image stored in the image file named |a2|, or |a2| does not exist in the
  40. // executable code's bundle.
  41. // If |a2| does not exist in the executable code's bundle, we save a image
  42. // representation of |a1| in the save directory with name |a2|. This can then
  43. // be included in the bundle as the master to test against.
  44. // If |a2| != |a1|, we save a image representation of |a1| in the save
  45. // directory named |a2|_Failed and a file named |a2|_Failed_Diff showing the
  46. // diff in red so that we can see what has changed.
  47. // See pathForImageNamed to see how name is searched for.
  48. // The save directory is specified by +gtm_setUnitTestSaveToDirectory, and is
  49. // the desktop by default.
  50. // Implemented as a macro to match the rest of the SenTest macros.
  51. //
  52. // Args:
  53. // a1: The object to be checked. Must implement the -createUnitTestImage method.
  54. // a2: The name of the image file to check against.
  55. // Do not include the extension
  56. // description: A format string as in the printf() function.
  57. // Can be nil or an empty string but must be present.
  58. // ...: A variable number of arguments to the format string. Can be absent.
  59. //
  60. #define GTMAssertObjectImageEqualToImageNamed(a1, a2, description, ...) \
  61. do { \
  62. id a1Object = (a1); \
  63. NSString* a2String = (a2); \
  64. NSString *failString = nil; \
  65. BOOL isGood = GTMIsObjectImageEqualToImageNamed(a1Object, a2String, &failString); \
  66. if (!isGood) { \
  67. if (description != nil) { \
  68. STFail(@"%@: %@", failString, STComposeString(description, ##__VA_ARGS__)); \
  69. } else { \
  70. STFail(@"%@", failString); \
  71. } \
  72. } \
  73. } while(0)
  74. // Fails when state of |a1| does not equal state in file |a2|
  75. //
  76. // Generates a failure when the unittest state of |a1| is not equal to the
  77. // state stored in the state file named |a2|, or |a2| does not exist in the
  78. // executable code's bundle.
  79. // If |a2| does not exist in the executable code's bundle, we save a state
  80. // representation of |a1| in the save directiry with name |a2|. This can then
  81. // be included in the bundle as the master to test against.
  82. // If |a2| != |a1|, we save a state representation of |a1| in the save
  83. // directory with name |a2|_Failed so that we can compare the two files to see
  84. // what has changed.
  85. // The save directory is specified by +gtm_setUnitTestSaveToDirectory, and is
  86. // the desktop by default.
  87. // Implemented as a macro to match the rest of the SenTest macros.
  88. //
  89. // Args:
  90. // a1: The object to be checked. Must implement the -createUnitTestImage method.
  91. // a2: The name of the state file to check against.
  92. // Do not include the extension
  93. // description: A format string as in the printf() function.
  94. // Can be nil or an empty string but must be present.
  95. // ...: A variable number of arguments to the format string. Can be absent.
  96. //
  97. #define GTMAssertObjectStateEqualToStateNamed(a1, a2, description, ...) \
  98. do { \
  99. id a1Object = (a1); \
  100. NSString* a2String = (a2); \
  101. NSString *failString = nil; \
  102. BOOL isGood = GTMIsObjectStateEqualToStateNamed(a1Object, a2String, &failString); \
  103. if (!isGood) { \
  104. if (description != nil) { \
  105. STFail(@"%@: %@", failString, STComposeString(description, ##__VA_ARGS__)); \
  106. } else { \
  107. STFail(@"%@", failString); \
  108. } \
  109. } \
  110. } while(0);
  111. // test both GTMAssertObjectImageEqualToImageNamed and GTMAssertObjectStateEqualToStateNamed
  112. //
  113. // Combines the above two macros into a single ubermacro for comparing
  114. // both state and image. When only the best will do...
  115. #define GTMAssertObjectEqualToStateAndImageNamed(a1, a2, description, ...) \
  116. do { \
  117. GTMAssertObjectImageEqualToImageNamed(a1, a2, description, ##__VA_ARGS__); \
  118. GTMAssertObjectStateEqualToStateNamed(a1, a2, description, ##__VA_ARGS__); \
  119. } while (0)
  120. // Create a CGBitmapContextRef appropriate for using in creating a unit test
  121. // image. If data is non-NULL, returns the buffer that the bitmap is
  122. // using for it's underlying storage. You must free this buffer using
  123. // free. If data is NULL, uses it's own internal storage.
  124. // Defined as a C function instead of an obj-c method because you have to
  125. // release the CGContextRef that is returned.
  126. //
  127. // Returns:
  128. // an CGContextRef of the object. Caller must release
  129. CGContextRef GTMCreateUnitTestBitmapContextOfSizeWithData(CGSize size,
  130. unsigned char **data);
  131. // GTMUnitTestingImaging protocol is for objects which need to save their
  132. // image for using with the unit testing categories
  133. @protocol GTMUnitTestingImaging
  134. // Create a CGImageRef containing a representation suitable for use in
  135. // comparing against a master image.
  136. //
  137. // Returns:
  138. // an CGImageRef of the object.
  139. - (CGImageRef)gtm_unitTestImage;
  140. @end
  141. // GTMUnitTestingEncoding protocol is for objects which need to save their
  142. // "state" for using with the unit testing categories
  143. @protocol GTMUnitTestingEncoding
  144. // Encodes the state of an object in a manner suitable for comparing
  145. // against a master state file so we can determine whether the
  146. // object is in a suitable state. Encode data in the coder in the same
  147. // manner that you would encode data in any other Keyed NSCoder subclass.
  148. //
  149. // Arguments:
  150. // inCoder - the coder to encode our state into
  151. - (void)gtm_unitTestEncodeState:(NSCoder*)inCoder;
  152. @end
  153. // Category for saving and comparing object state and image for unit tests
  154. //
  155. // The GTMUnitTestAdditions category gives object the ability to store their
  156. // state for use in unittesting in two different manners.
  157. // 1) Objects can elect to save their "image" that we can compare at
  158. // runtime to an image file to make sure that the representation hasn't
  159. // changed. All views and Windows can save their image. In the case of Windows,
  160. // they are "bluescreened" so that any transparent areas can be compared between
  161. // machines.
  162. // 2) Objects can elect to save their "state". State is the attributes that we
  163. // want to verify when running unit tests. Applications, Windows, Views,
  164. // Controls and Cells currently return a variety of state information. If you
  165. // want to customize the state information that a particular object returns, you
  166. // can do it via the GTMUnitTestingEncodedObjectNotification. Items that have
  167. // delegates (Applications/Windows) can also have their delegates return state
  168. // information if appropriate via the unitTestEncoderDidEncode:inCoder: delegate
  169. // method.
  170. // To compare state/image in your unit tests, you can use the three macros above
  171. // GTMAssertObjectStateEqualToStateNamed, GTMAssertObjectImageEqualToImageNamed and
  172. // GTMAssertObjectEqualToStateAndImageNamed.
  173. @interface NSObject (GTMUnitTestingAdditions) <GTMUnitTestingEncoding>
  174. // Allows you to control where the unit test utilities save any files
  175. // (image or state) that they create on your behalf. By default they
  176. // will save to the desktop.
  177. + (void)gtm_setUnitTestSaveToDirectory:(NSString*)path;
  178. + (NSString *)gtm_getUnitTestSaveToDirectory;
  179. // Checks to see that system settings are valid for doing an image comparison.
  180. // Most of these are set by our unit test app. See the unit test app main.m
  181. // for details.
  182. //
  183. // Returns:
  184. // YES if we can do image comparisons for this object type.
  185. - (BOOL)gtm_areSystemSettingsValidForDoingImage;
  186. // Return the type of image to work with. Only valid types on the iPhone
  187. // are kUTTypeJPEG and kUTTypePNG. MacOS supports several more.
  188. - (CFStringRef)gtm_imageUTI;
  189. // Return the extension to be used for saving unittest images
  190. //
  191. // Returns
  192. // An extension (e.g. "png")
  193. - (NSString*)gtm_imageExtension;
  194. // Return image data in the format expected for gtm_imageExtension
  195. // So for a "png" extension I would expect "png" data
  196. //
  197. // Returns
  198. // NSData for image
  199. - (NSData*)gtm_imageDataForImage:(CGImageRef)image;
  200. // Save the unitTestImage to a image file with name
  201. // |name|.arch.OSVersionMajor.OSVersionMinor.OSVersionBugfix.extension
  202. // in the save folder (desktop by default)
  203. //
  204. // Args:
  205. // name: The name for the image file you would like saved.
  206. //
  207. // Returns:
  208. // YES if the file was successfully saved.
  209. //
  210. - (BOOL)gtm_saveToImageNamed:(NSString*)name;
  211. // Save unitTestImage of |self| to an image file at path |path|.
  212. // All non-drawn areas will be transparent.
  213. //
  214. // Args:
  215. // name: The name for the image file you would like saved.
  216. //
  217. // Returns:
  218. // YES if the file was successfully saved.
  219. //
  220. - (BOOL)gtm_saveToImageAt:(NSString*)path;
  221. // Compares unitTestImage of |self| to the image located at |path|
  222. //
  223. // Args:
  224. // path: the path to the image file you want to compare against.
  225. // If diff is non-nil, it will contain an auto-released diff of the images.
  226. //
  227. // Returns:
  228. // YES if they are equal, NO is they are not
  229. // If diff is non-nil, it will contain a diff of the images. Must
  230. // be released by caller.
  231. //
  232. - (BOOL)gtm_compareWithImageAt:(NSString*)path diffImage:(CGImageRef*)diff;
  233. // Find the path for a image by name in your bundle.
  234. // Searches for the following:
  235. // "name.CompilerSDK.OSVersionMajor.OSVersionMinor.OSVersionBugFix.arch.extension"
  236. // "name.CompilerSDK.OSVersionMajor.OSVersionMinor.arch.extension"
  237. // "name.CompilerSDK.OSVersionMajor.arch.extension"
  238. // "name.CompilerSDK.arch.extension"
  239. // "name.CompilerSDK.OSVersionMajor.OSVersionMinor.OSVersionBugFix.extension"
  240. // "name.CompilerSDK.OSVersionMajor.OSVersionMinor.extension"
  241. // "name.CompilerSDK.OSVersionMajor.extension"
  242. // "name.CompilerSDK.extension"
  243. // "name.OSVersionMajor.OSVersionMinor.OSVersionBugFix.arch.extension"
  244. // "name.OSVersionMajor.OSVersionMinor.arch.extension"
  245. // "name.OSVersionMajor.arch.extension"
  246. // "name.arch.extension"
  247. // "name.OSVersionMajor.OSVersionMinor.OSVersionBugFix.extension"
  248. // "name.OSVersionMajor.OSVersionMinor.extension"
  249. // "name.OSVersionMajor.extension"
  250. // "name.extension"
  251. // Do not include the extension on your name.
  252. //
  253. // Args:
  254. // name: The name for the image file you would like to find.
  255. //
  256. // Returns:
  257. // the path if the image exists in your bundle
  258. // or nil if no image to be found
  259. //
  260. - (NSString *)gtm_pathForImageNamed:(NSString*)name;
  261. // Generates a CGImageRef from the image at |path|
  262. // Args:
  263. // path: The path to the image.
  264. //
  265. // Returns:
  266. // An autoreleased CGImageRef own, or nil if no image at path
  267. - (CGImageRef)gtm_imageWithContentsOfFile:(NSString*)path;
  268. // Generates a path for a image in the save directory, which is desktop
  269. // by default.
  270. // Path will be:
  271. // SaveDir/|name|.arch.OSVersionMajor.OSVersionMinor.OSVersionBugfix.extension
  272. //
  273. // Args:
  274. // name: The name for the image file you would like to generate a path for.
  275. //
  276. // Returns:
  277. // the path
  278. //
  279. - (NSString *)gtm_saveToPathForImageNamed:(NSString*)name;
  280. // Gives us a representation of unitTestImage of |self|.
  281. //
  282. // Returns:
  283. // a representation if successful
  284. // nil if failed
  285. //
  286. - (NSData *)gtm_imageRepresentation;
  287. // Return the extension to be used for saving unittest states
  288. //
  289. // Returns
  290. // An extension (e.g. "gtmUTState")
  291. - (NSString*)gtm_stateExtension;
  292. // Save the encoded unit test state to a state file with name
  293. // |name|.arch.OSVersionMajor.OSVersionMinor.OSVersionBugfix.extension
  294. // in the save folder (desktop by default)
  295. //
  296. // Args:
  297. // name: The name for the state file you would like saved.
  298. //
  299. // Returns:
  300. // YES if the file was successfully saved.
  301. //
  302. - (BOOL)gtm_saveToStateNamed:(NSString*)name;
  303. // Save encoded unit test state of |self| to a state file at path |path|.
  304. //
  305. // Args:
  306. // name: The name for the state file you would like saved.
  307. //
  308. // Returns:
  309. // YES if the file was successfully saved.
  310. //
  311. - (BOOL)gtm_saveToStateAt:(NSString*)path;
  312. // Compares encoded unit test state of |self| to the state file located at |path|
  313. //
  314. // Args:
  315. // path: the path to the state file you want to compare against.
  316. //
  317. // Returns:
  318. // YES if they are equal, NO is they are not
  319. //
  320. - (BOOL)gtm_compareWithStateAt:(NSString*)path;
  321. // Find the path for a state by name in your bundle.
  322. // Searches for:
  323. // "name.CompilerSDK.OSVersionMajor.OSVersionMinor.OSVersionBugFix.arch.extension"
  324. // "name.CompilerSDK.OSVersionMajor.OSVersionMinor.arch.extension"
  325. // "name.CompilerSDK.OSVersionMajor.arch.extension"
  326. // "name.CompilerSDK.arch.extension"
  327. // "name.CompilerSDK.OSVersionMajor.OSVersionMinor.OSVersionBugFix.extension"
  328. // "name.CompilerSDK.OSVersionMajor.OSVersionMinor.extension"
  329. // "name.CompilerSDK.OSVersionMajor.extension"
  330. // "name.CompilerSDK.extension"
  331. // "name.OSVersionMajor.OSVersionMinor.OSVersionBugFix.arch.extension"
  332. // "name.OSVersionMajor.OSVersionMinor.arch.extension"
  333. // "name.OSVersionMajor.arch.extension"
  334. // "name.arch.extension"
  335. // "name.OSVersionMajor.OSVersionMinor.OSVersionBugFix.extension"
  336. // "name.OSVersionMajor.OSVersionMinor.extension"
  337. // "name.OSVersionMajor.extension"
  338. // "name.extension"
  339. // Do not include the extension on your name.
  340. //
  341. // Args:
  342. // name: The name for the state file you would like to find.
  343. //
  344. // Returns:
  345. // the path if the state exists in your bundle
  346. // or nil if no state to be found
  347. //
  348. - (NSString *)gtm_pathForStateNamed:(NSString*)name;
  349. // Generates a path for a state in the save directory, which is desktop
  350. // by default.
  351. // Path will be:
  352. // SaveDir/|name|.arch.OSVersionMajor.OSVersionMinor.OSVersionBugfix.extension
  353. //
  354. // Args:
  355. // name: The name for the state file you would like to generate a path for.
  356. //
  357. // Returns:
  358. // the path
  359. //
  360. - (NSString *)gtm_saveToPathForStateNamed:(NSString*)name;
  361. // Gives us the encoded unit test state for |self|
  362. //
  363. // Returns:
  364. // the encoded state if successful
  365. // nil if failed
  366. //
  367. - (NSDictionary *)gtm_stateRepresentation;
  368. // Encodes the state of an object in a manner suitable for comparing
  369. // against a master state file so we can determine whether the
  370. // object is in a suitable state. Encode data in the coder in the same
  371. // manner that you would encode data in any other Keyed NSCoder subclass.
  372. //
  373. // Arguments:
  374. // inCoder - the coder to encode our state into
  375. - (void)gtm_unitTestEncodeState:(NSCoder*)inCoder;
  376. @end
  377. // Informal protocol for delegates that wanst to be able to add state info
  378. // when state info is collected for their "owned" objects
  379. @interface NSObject (GTMUnitTestingEncodingAdditions)
  380. // Delegate function for unit test objects that have delegates. Delegates have
  381. // the option of encoding more data into the coder to store their state for
  382. // unittest usage.
  383. - (void)gtm_unitTestEncoderWillEncode:(id)sender inCoder:(NSCoder*)inCoder;
  384. @end
  385. // Whenever an object is encoded by the unit test encoder, it send out a
  386. // notification so that objects who want to add data to the encoded objects unit
  387. // test state can do so. The Coder will be in the userInfo dictionary for the
  388. // notification under the GTMUnitTestingEncoderKey key.
  389. GTM_EXTERN NSString *const GTMUnitTestingEncodedObjectNotification;
  390. // Key for finding the encoder in the userInfo dictionary for
  391. // GTMUnitTestingEncodedObjectNotification notifications.
  392. GTM_EXTERN NSString *const GTMUnitTestingEncoderKey;