/core/externals/google-toolbox-for-mac/UnitTesting/GTMFoundationUnitTestingUtilities.h

http://macfuse.googlecode.com/ · C Header · 107 lines · 28 code · 13 blank · 66 comment · 0 complexity · 0e1f17243f33e06e5718a526d30b00a5 MD5 · raw file

  1. //
  2. // GTMFoundationUnitTestingUtilities.h
  3. //
  4. // Copyright 2006-2010 Google Inc.
  5. //
  6. // Licensed under the Apache License, Version 2.0 (the "License"); you may not
  7. // use this file except in compliance with the License. You may obtain a copy
  8. // of the License at
  9. //
  10. // http://www.apache.org/licenses/LICENSE-2.0
  11. //
  12. // Unless required by applicable law or agreed to in writing, software
  13. // distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
  14. // WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
  15. // License for the specific language governing permissions and limitations under
  16. // the License.
  17. //
  18. #import <Foundation/Foundation.h>
  19. #import <objc/objc.h>
  20. // Many tests need to spin the runloop and wait for an event to happen. This is
  21. // often done by calling:
  22. // NSDate* next = [NSDate dateWithTimeIntervalSinceNow:resolution];
  23. // [[NSRunLoop currentRunLoop] runMode:NSDefaultRunLoopMode
  24. // beforeDate:next];
  25. // where |resolution| is a guess at how long it will take for the event to
  26. // happen. There are two major problems with this approach:
  27. // a) By guessing we force the test to take at least |resolution| time.
  28. // b) It makes for flaky tests in that sometimes this guess isn't good, and the
  29. // test takes slightly longer than |resolution| time causing the test to post
  30. // a possibly false-negative failure.
  31. // To make timing callback tests easier use this class and the
  32. // GTMUnitTestingAdditions additions to NSRunLoop and NSApplication.
  33. // Your call would look something like this:
  34. // id<GTMUnitTestingRunLoopContext> context = [self getMeAContext];
  35. // [[NSRunLoop currentRunLoop] gtm_runUpToSixtySecondsWithContext:context];
  36. // Then in some callback method within your test you would call
  37. // [context setShouldStop:YES];
  38. // Internally gtm_runUpToSixtySecondsWithContext will poll the runloop really
  39. // quickly to keep test times down to a minimum, but will stop after a good time
  40. // interval (in this case 60 seconds) for failures.
  41. @protocol GTMUnitTestingRunLoopContext
  42. // Return YES if the NSRunLoop (or equivalent) that this context applies to
  43. // should stop as soon as possible.
  44. - (BOOL)shouldStop;
  45. @end
  46. // Collection of utilities for unit testing
  47. @interface GTMFoundationUnitTestingUtilities : NSObject
  48. // Returns YES if we are currently being unittested.
  49. + (BOOL)areWeBeingUnitTested;
  50. // Installs a timer to quit the process after the given time, as a catch all for
  51. // something not working. There is a problem that of the testing bundle fails
  52. // to load when is is being hosted in a custom app, the app will remain running
  53. // until the user quits it. This provides a way out of that. When the timer
  54. // fires, a message is logged, and the process is directly exited, no clean
  55. // shutdown. This requires a runloop be running.
  56. + (void)installTestingTimeout:(NSTimeInterval)maxRunInterval;
  57. @end
  58. // An implementation of the GTMUnitTestingRunLoopContext that is a simple
  59. // BOOL flag. See GTMUnitTestingRunLoopContext documentation.
  60. @interface GTMUnitTestingBooleanRunLoopContext : NSObject <GTMUnitTestingRunLoopContext> {
  61. @private
  62. BOOL shouldStop_;
  63. }
  64. + (id)context;
  65. - (BOOL)shouldStop;
  66. - (void)setShouldStop:(BOOL)stop;
  67. - (void)reset;
  68. @end
  69. // Some category methods to simplify spinning the runloops in such a way as
  70. // to make tests less flaky, but have them complete as fast as possible.
  71. @interface NSRunLoop (GTMUnitTestingAdditions)
  72. // Will spin the runloop in mode until date in mode until the runloop returns
  73. // because all sources have been removed or the current date is greater than
  74. // |date| or [context shouldStop] returns YES.
  75. // Return YES if the runloop was stopped because [context shouldStop] returned
  76. // YES.
  77. - (BOOL)gtm_runUntilDate:(NSDate *)date
  78. mode:(NSString *)mode
  79. context:(id<GTMUnitTestingRunLoopContext>)context;
  80. // Calls -gtm_runUntilDate:mode:context: with mode set to NSDefaultRunLoopMode.
  81. - (BOOL)gtm_runUntilDate:(NSDate *)date
  82. context:(id<GTMUnitTestingRunLoopContext>)context;
  83. // Calls -gtm_runUntilDate:mode:context: with mode set to NSDefaultRunLoopMode,
  84. // and the timeout date set to |seconds| seconds.
  85. - (BOOL)gtm_runUpToNSeconds:(NSTimeInterval)seconds
  86. context:(id<GTMUnitTestingRunLoopContext>)context;
  87. // Calls -gtm_runUntilDate:mode:context: with mode set to NSDefaultRunLoopMode,
  88. // and the timeout date set to 60 seconds.
  89. // This is a good time to use for AppleEvent calls (which default to 60 seconds)
  90. // but may be a bit long for standard unit tests, and could cause a long unit
  91. // testing run if you have multiple failures.
  92. // Calling -[gtm_runUpToNSeconds:context:] is preferred.
  93. - (BOOL)gtm_runUpToSixtySecondsWithContext:(id<GTMUnitTestingRunLoopContext>)context;
  94. @end