/core/externals/update-engine/externals/google-toolbox-for-mac/AppKit/GTMCarbonEventTest.m

http://macfuse.googlecode.com/ · Objective C · 384 lines · 291 code · 62 blank · 31 comment · 11 complexity · b2fcc2195e317b06d0cb42d8f2102709 MD5 · raw file

  1. //
  2. // GTMCarbonEventTest.m
  3. //
  4. // Copyright 2006-2008 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 "GTMSenTestCase.h"
  19. #import "GTMCarbonEvent.h"
  20. #import "GTMAppKitUnitTestingUtilities.h"
  21. #import "GTMUnitTestDevLog.h"
  22. @interface GTMCarbonEventTest : GTMTestCase {
  23. @private
  24. GTMCarbonEvent *event_;
  25. }
  26. @end
  27. @interface GTMCarbonEventHandlerTest : GTMTestCase {
  28. @private
  29. GTMCarbonEventHandler *handler_;
  30. }
  31. @end
  32. @interface GTMCarbonEventMonitorHandlerTest : GTMTestCase
  33. @end
  34. @interface GTMCarbonEventApplicationEventHandlerTest : GTMTestCase
  35. @end
  36. @interface GTMCarbonEventDispatcherHandlerTest : GTMTestCase {
  37. @private
  38. GTMUnitTestingBooleanRunLoopContext *hotKeyHit_;
  39. }
  40. @end
  41. static const UInt32 kTestClass = 'foo ';
  42. static const UInt32 kTestKind = 'bar ';
  43. static const UInt32 kTestParameterName = 'baz ';
  44. static const UInt32 kTestBadParameterName = 'bom ';
  45. static const UInt32 kTestParameterValue = 'bam ';
  46. @implementation GTMCarbonEventTest
  47. - (void)setUp {
  48. event_ = [[GTMCarbonEvent eventWithClass:kTestClass kind:kTestKind] retain];
  49. }
  50. - (void)tearDown {
  51. [event_ release];
  52. }
  53. - (void)testCopy {
  54. GTMCarbonEvent *event2 = [[event_ copy] autorelease];
  55. STAssertNotNil(event2, nil);
  56. }
  57. - (void)testEventWithClassAndKind {
  58. STAssertEquals([event_ eventClass], kTestClass, nil);
  59. STAssertEquals([event_ eventKind], kTestKind, nil);
  60. }
  61. - (void)testEventWithEvent {
  62. GTMCarbonEvent *event2 = [GTMCarbonEvent eventWithEvent:[event_ event]];
  63. STAssertEquals([event2 event], [event_ event], nil);
  64. }
  65. - (void)testCurrentEvent {
  66. EventRef eventRef = GetCurrentEvent();
  67. GTMCarbonEvent *event = [GTMCarbonEvent currentEvent];
  68. STAssertEquals([event event], eventRef, nil);
  69. }
  70. - (void)testEventClass {
  71. [self testEventWithClassAndKind];
  72. }
  73. - (void)testEventKind {
  74. [self testEventWithClassAndKind];
  75. }
  76. - (void)testSetTime {
  77. EventTime eventTime = [event_ time];
  78. STAssertNotEquals(eventTime, kEventDurationNoWait, nil);
  79. STAssertNotEquals(eventTime, kEventDurationForever, nil);
  80. [event_ setTime:kEventDurationForever];
  81. EventTime testTime = [event_ time];
  82. STAssertEquals(testTime, kEventDurationForever, nil);
  83. [event_ setTime:eventTime];
  84. STAssertEquals([event_ time], eventTime, nil);
  85. }
  86. - (void)testTime {
  87. [self testSetTime];
  88. }
  89. - (void)testEvent {
  90. [self testEventWithEvent];
  91. }
  92. - (void)testSetParameterNamed {
  93. UInt32 theData = kTestParameterValue;
  94. [event_ setUInt32ParameterNamed:kTestParameterName data:&theData];
  95. theData = 0;
  96. STAssertEquals([event_ sizeOfParameterNamed:kTestParameterName
  97. type:typeUInt32],
  98. sizeof(UInt32), nil);
  99. STAssertTrue([event_ getUInt32ParameterNamed:kTestParameterName
  100. data:&theData], nil);
  101. STAssertEquals(theData, kTestParameterValue, nil);
  102. }
  103. - (void)testGetParameterNamed {
  104. [self testSetParameterNamed];
  105. UInt32 theData = kTestParameterValue;
  106. STAssertFalse([event_ getUInt32ParameterNamed:kTestBadParameterName
  107. data:&theData], nil);
  108. STAssertFalse([event_ getUInt32ParameterNamed:kTestBadParameterName
  109. data:NULL], nil);
  110. }
  111. - (void)testSizeOfParameterNamed {
  112. [self testSetParameterNamed];
  113. }
  114. - (void)testHasParameterNamed {
  115. [self testSetParameterNamed];
  116. }
  117. - (OSStatus)gtm_eventHandler:(GTMCarbonEventHandler *)sender
  118. receivedEvent:(GTMCarbonEvent *)event
  119. handler:(EventHandlerCallRef)handler {
  120. OSStatus status = eventNotHandledErr;
  121. if ([event eventClass] == kTestClass && [event eventKind] == kTestKind) {
  122. status = noErr;
  123. }
  124. return status;
  125. }
  126. - (void)testSendToTarget {
  127. EventTypeSpec types = { kTestClass, kTestKind };
  128. GTMCarbonEventDispatcherHandler *handler
  129. = [[GTMCarbonEventDispatcherHandler sharedEventDispatcherHandler]
  130. autorelease];
  131. [handler registerForEvents:&types count:1];
  132. OSStatus status = [event_ sendToTarget:handler options:0];
  133. STAssertErr(status, eventNotHandledErr, @"status: %ld", (long)status);
  134. [handler setDelegate:self];
  135. status = [event_ sendToTarget:handler options:0];
  136. STAssertNoErr(status, @"status: %ld", (long)status);
  137. [handler unregisterForEvents:&types count:1];
  138. }
  139. - (void)testPostToQueue {
  140. EventQueueRef eventQueue = GetMainEventQueue();
  141. [event_ postToMainQueue];
  142. OSStatus status = [event_ postToQueue:eventQueue
  143. priority:kEventPriorityStandard];
  144. STAssertErr(status, eventAlreadyPostedErr, @"status: %ld", (long)status);
  145. EventTypeSpec types = { kTestClass, kTestKind };
  146. status = FlushEventsMatchingListFromQueue(eventQueue, 1, &types);
  147. STAssertNoErr(status, @"status: %ld", (long)status);
  148. eventQueue = GetCurrentEventQueue();
  149. [event_ postToCurrentQueue];
  150. status = [event_ postToQueue:eventQueue priority:kEventPriorityStandard];
  151. STAssertErr(status, eventAlreadyPostedErr, @"status: %ld", (long)status);
  152. status = FlushEventsMatchingListFromQueue(eventQueue, 1, &types);
  153. STAssertNoErr(status, @"status: %ld", status);
  154. }
  155. - (void)testPostToMainQueue {
  156. [self testPostToQueue];
  157. }
  158. - (void)testPostToCurrentQueue {
  159. STAssertEquals(GetCurrentEventQueue(), GetMainEventQueue(), nil);
  160. [self testPostToMainQueue];
  161. }
  162. - (void)testDescription {
  163. NSString *descString
  164. = [NSString stringWithFormat:@"GTMCarbonEvent 'foo ' %lu",
  165. (unsigned long)kTestKind];
  166. STAssertEqualObjects([event_ description], descString, nil);
  167. }
  168. @end
  169. @implementation GTMCarbonEventHandlerTest
  170. - (void)setUp {
  171. handler_ = [[GTMCarbonEventHandler alloc] init];
  172. }
  173. - (void)tearDown {
  174. [handler_ release];
  175. }
  176. - (void)testEventTarget {
  177. STAssertNULL([handler_ eventTarget], nil);
  178. }
  179. - (void)testEventHandler {
  180. [GTMUnitTestDevLogDebug expectPattern:
  181. @"DebugAssert: GoogleToolboxForMac: event CantUseParams .*"];
  182. STAssertErr([handler_ handleEvent:nil handler:nil],
  183. (long)eventNotHandledErr, nil);
  184. }
  185. - (void)testDelegate {
  186. [handler_ setDelegate:self];
  187. STAssertEqualObjects([handler_ delegate], self, nil);
  188. [handler_ setDelegate:nil];
  189. STAssertNil([handler_ delegate], nil);
  190. }
  191. - (void)testSetDelegate {
  192. [self testDelegate];
  193. }
  194. @end
  195. @implementation GTMCarbonEventMonitorHandlerTest
  196. - (void)testEventHandler {
  197. GTMCarbonEventMonitorHandler *monitor
  198. = [GTMCarbonEventMonitorHandler sharedEventMonitorHandler];
  199. STAssertEquals([monitor eventTarget], GetEventMonitorTarget(), nil);
  200. }
  201. @end
  202. #if (MAC_OS_X_VERSION_MAX_ALLOWED == MAC_OS_X_VERSION_10_5)
  203. // Accidentally marked as !LP64 in the 10.5sdk, it's back in the 10.6 sdk.
  204. // If you remove this decl, please remove it from GTMCarbonEvent.m as well.
  205. extern EventTargetRef GetApplicationEventTarget(void);
  206. #endif // (MAC_OS_X_VERSION_MAX_ALLOWED == MAC_OS_X_VERSION_10_5)
  207. @implementation GTMCarbonEventApplicationEventHandlerTest
  208. - (void)testEventHandler {
  209. GTMCarbonEventApplicationEventHandler *handler
  210. = [GTMCarbonEventApplicationEventHandler sharedApplicationEventHandler];
  211. STAssertEquals([handler eventTarget], GetApplicationEventTarget(), nil);
  212. }
  213. @end
  214. @implementation GTMCarbonEventDispatcherHandlerTest
  215. - (void)setUp {
  216. hotKeyHit_ = [[GTMUnitTestingBooleanRunLoopContext alloc] init];
  217. }
  218. - (void)tearDown {
  219. [hotKeyHit_ release];
  220. hotKeyHit_ = nil;
  221. }
  222. - (void)testEventHandler {
  223. GTMCarbonEventDispatcherHandler *dispatcher
  224. = [GTMCarbonEventDispatcherHandler sharedEventDispatcherHandler];
  225. STAssertEquals([dispatcher eventTarget], GetEventDispatcherTarget(), nil);
  226. }
  227. - (void)hitHotKey:(GTMCarbonHotKey *)key {
  228. STAssertEqualObjects([key userInfo], self, nil);
  229. [hotKeyHit_ setShouldStop:YES];
  230. }
  231. - (void)hitExceptionalHotKey:(GTMCarbonHotKey *)key {
  232. STAssertEqualObjects([key userInfo], self, nil);
  233. [hotKeyHit_ setShouldStop:YES];
  234. [NSException raise:@"foo" format:@"bar"];
  235. }
  236. - (void)testRegisterHotKeyModifiersTargetActionWhenPressed {
  237. // This test can't be run if the screen saver is active because the security
  238. // agent blocks us from sending events via remote operations
  239. if (![GTMAppKitUnitTestingUtilities isScreenSaverActive]) {
  240. GTMCarbonEventDispatcherHandler *dispatcher
  241. = [GTMCarbonEventDispatcherHandler sharedEventDispatcherHandler];
  242. STAssertNotNil(dispatcher, @"Unable to acquire singleton");
  243. UInt32 keyMods = (NSShiftKeyMask | NSControlKeyMask
  244. | NSAlternateKeyMask | NSCommandKeyMask);
  245. [GTMUnitTestDevLogDebug expectPattern:@"DebugAssert: GoogleToolboxForMac: "
  246. @"newKey CantCreateKey .*"];
  247. STAssertNil([dispatcher registerHotKey:0x5
  248. modifiers:keyMods
  249. target:nil
  250. action:nil
  251. userInfo:nil
  252. whenPressed:YES],
  253. @"Shouldn't have created hotkey");
  254. GTMCarbonHotKey *hotKey = [dispatcher registerHotKey:0x5
  255. modifiers:keyMods
  256. target:self
  257. action:@selector(hitHotKey:)
  258. userInfo:self
  259. whenPressed:YES];
  260. STAssertNotNil(hotKey, @"Unable to create hotkey");
  261. // Post the hotkey combo to the event queue. If everything is working
  262. // correctly hitHotKey: should get called, and hotKeyHit_ will be set for
  263. // us. We run the event loop for a set amount of time waiting for this to
  264. // happen.
  265. [GTMAppKitUnitTestingUtilities postTypeCharacterEvent:'g' modifiers:keyMods];
  266. STAssertTrue([NSApp gtm_runUpToSixtySecondsWithContext:hotKeyHit_], nil);
  267. [dispatcher unregisterHotKey:hotKey];
  268. }
  269. }
  270. - (void)testRegisterHotKeyModifiersTargetActionWhenPressedException {
  271. // This test can't be run if the screen saver is active because the security
  272. // agent blocks us from sending events via remote operations
  273. if (![GTMAppKitUnitTestingUtilities isScreenSaverActive]) {
  274. GTMCarbonEventDispatcherHandler *dispatcher
  275. = [GTMCarbonEventDispatcherHandler sharedEventDispatcherHandler];
  276. STAssertNotNil(dispatcher, @"Unable to acquire singleton");
  277. UInt32 keyMods = (NSShiftKeyMask | NSControlKeyMask
  278. | NSAlternateKeyMask | NSCommandKeyMask);
  279. GTMCarbonHotKey *hotKey
  280. = [dispatcher registerHotKey:0x5
  281. modifiers:keyMods
  282. target:self
  283. action:@selector(hitExceptionalHotKey:)
  284. userInfo:self
  285. whenPressed:YES];
  286. STAssertNotNil(hotKey, @"Unable to create hotkey");
  287. // Post the hotkey combo to the event queue. If everything is working
  288. // correctly hitHotKey: should get called, and hotKeyHit_ will be set for
  289. // us. We run the event loop for a set amount of time waiting for this to
  290. // happen.
  291. [GTMAppKitUnitTestingUtilities postTypeCharacterEvent:'g' modifiers:keyMods];
  292. [GTMUnitTestDevLog expectString:@"Exception fired in hotkey: foo (bar)"];
  293. STAssertTrue([NSApp gtm_runUpToSixtySecondsWithContext:hotKeyHit_], nil);
  294. [dispatcher unregisterHotKey:hotKey];
  295. }
  296. }
  297. - (void)testKeyModifiers {
  298. struct {
  299. NSUInteger cocoaKey_;
  300. UInt32 carbonKey_;
  301. } keyMap[] = {
  302. { NSAlphaShiftKeyMask, alphaLock},
  303. { NSShiftKeyMask, shiftKey},
  304. { NSControlKeyMask, controlKey},
  305. { NSAlternateKeyMask, optionKey},
  306. { NSCommandKeyMask, cmdKey},
  307. };
  308. size_t combos = pow(2, sizeof(keyMap) / sizeof(keyMap[0]));
  309. for (size_t i = 0; i < combos; i++) {
  310. NSUInteger cocoaMods = 0;
  311. UInt32 carbonMods = 0;
  312. for (size_t j = 0; j < 32 && j < sizeof(keyMap) / sizeof(keyMap[0]); j++) {
  313. if (i & 1 << j) {
  314. cocoaMods |= keyMap[j].cocoaKey_;
  315. carbonMods |= keyMap[j].carbonKey_;
  316. }
  317. }
  318. STAssertEquals(GTMCocoaToCarbonKeyModifiers(cocoaMods), carbonMods, nil);
  319. STAssertEquals(GTMCarbonToCocoaKeyModifiers(carbonMods), cocoaMods, nil);
  320. }
  321. }
  322. @end