aboutsummaryrefslogtreecommitdiff
path: root/AppKit/GTMCarbonEventTest.m
diff options
context:
space:
mode:
Diffstat (limited to 'AppKit/GTMCarbonEventTest.m')
-rw-r--r--AppKit/GTMCarbonEventTest.m360
1 files changed, 360 insertions, 0 deletions
diff --git a/AppKit/GTMCarbonEventTest.m b/AppKit/GTMCarbonEventTest.m
new file mode 100644
index 0000000..0615271
--- /dev/null
+++ b/AppKit/GTMCarbonEventTest.m
@@ -0,0 +1,360 @@
+//
+// GTMCarbonEventTest.m
+//
+// Copyright 2006-2008 Google Inc.
+//
+// Licensed under the Apache License, Version 2.0 (the "License"); you may not
+// use this file except in compliance with the License. You may obtain a copy
+// of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+// License for the specific language governing permissions and limitations under
+// the License.
+//
+
+#import "GTMSenTestCase.h"
+#import "GTMCarbonEvent.h"
+#import "GTMUnitTestingUtilities.h"
+#import "GTMUnitTestDevLog.h"
+
+@interface GTMCarbonEventTest : GTMTestCase {
+ @private
+ GTMCarbonEvent *event_;
+}
+@end
+
+@interface GTMCarbonEventHandlerTest : GTMTestCase {
+ @private
+ GTMCarbonEventHandler *handler_;
+}
+@end
+
+@interface GTMCarbonEventMonitorHandlerTest : GTMTestCase
+@end
+
+@interface GTMCarbonEventDispatcherHandlerTest : GTMTestCase {
+ @private
+ BOOL hotKeyHit_;
+}
+@end
+
+static const UInt32 kTestClass = 'foo ';
+static const UInt32 kTestKind = 'bar ';
+static const UInt32 kTestParameterName = 'baz ';
+static const UInt32 kTestBadParameterName = 'bom ';
+static const UInt32 kTestParameterValue = 'bam ';
+
+@implementation GTMCarbonEventTest
+- (void)setUp {
+ event_ = [[GTMCarbonEvent eventWithClass:kTestClass kind:kTestKind] retain];
+}
+
+- (void)tearDown {
+ [event_ release];
+}
+
+- (void)testCopy {
+ GTMCarbonEvent *event2 = [[event_ copy] autorelease];
+ STAssertNotNil(event2, nil);
+}
+
+- (void)testEventWithClassAndKind {
+ STAssertEquals([event_ eventClass], kTestClass, nil);
+ STAssertEquals([event_ eventKind], kTestKind, nil);
+}
+
+- (void)testEventWithEvent {
+ GTMCarbonEvent *event2 = [GTMCarbonEvent eventWithEvent:[event_ event]];
+ STAssertEquals([event2 event], [event_ event], nil);
+}
+
+- (void)testCurrentEvent {
+ EventRef eventRef = GetCurrentEvent();
+ GTMCarbonEvent *event = [GTMCarbonEvent currentEvent];
+ STAssertEquals([event event], eventRef, nil);
+}
+
+- (void)testEventClass {
+ [self testEventWithClassAndKind];
+}
+
+- (void)testEventKind {
+ [self testEventWithClassAndKind];
+}
+
+- (void)testSetTime {
+ EventTime eventTime = [event_ time];
+ STAssertNotEquals(eventTime, kEventDurationNoWait, nil);
+ STAssertNotEquals(eventTime, kEventDurationForever, nil);
+ [event_ setTime:kEventDurationForever];
+ EventTime testTime = [event_ time];
+ STAssertEquals(testTime, kEventDurationForever, nil);
+ [event_ setTime:eventTime];
+ STAssertEquals([event_ time], eventTime, nil);
+}
+
+- (void)testTime {
+ [self testSetTime];
+}
+
+- (void)testEvent {
+ [self testEventWithEvent];
+}
+
+- (void)testSetParameterNamed {
+ UInt32 theData = kTestParameterValue;
+ [event_ setUInt32ParameterNamed:kTestParameterName data:&theData];
+ theData = 0;
+ STAssertEquals([event_ sizeOfParameterNamed:kTestParameterName
+ type:typeUInt32],
+ sizeof(UInt32), nil);
+ STAssertTrue([event_ getUInt32ParameterNamed:kTestParameterName
+ data:&theData], nil);
+ STAssertEquals(theData, kTestParameterValue, nil);
+}
+
+- (void)testGetParameterNamed {
+ [self testSetParameterNamed];
+ UInt32 theData = kTestParameterValue;
+ STAssertFalse([event_ getUInt32ParameterNamed:kTestBadParameterName
+ data:&theData], nil);
+ STAssertFalse([event_ getUInt32ParameterNamed:kTestBadParameterName
+ data:NULL], nil);
+
+}
+
+- (void)testSizeOfParameterNamed {
+ [self testSetParameterNamed];
+}
+
+- (void)testHasParameterNamed {
+ [self testSetParameterNamed];
+}
+
+- (OSStatus)gtm_eventHandler:(GTMCarbonEventHandler *)sender
+ receivedEvent:(GTMCarbonEvent *)event
+ handler:(EventHandlerCallRef)handler {
+ OSStatus status = eventNotHandledErr;
+ if ([event eventClass] == kTestClass && [event eventKind] == kTestKind) {
+ status = noErr;
+ }
+ return status;
+}
+
+- (void)testSendToTarget {
+ EventTypeSpec types = { kTestClass, kTestKind };
+ GTMCarbonEventDispatcherHandler *handler
+ = [[GTMCarbonEventDispatcherHandler sharedEventDispatcherHandler]
+ autorelease];
+ [handler registerForEvents:&types count:1];
+ OSStatus status = [event_ sendToTarget:handler options:0];
+ STAssertErr(status, eventNotHandledErr, @"status: %ld", status);
+ [handler setDelegate:self];
+ status = [event_ sendToTarget:handler options:0];
+ STAssertNoErr(status, @"status: %ld", status);
+ [handler unregisterForEvents:&types count:1];
+}
+
+- (void)testPostToQueue {
+ EventQueueRef eventQueue = GetMainEventQueue();
+ [event_ postToMainQueue];
+ OSStatus status = [event_ postToQueue:eventQueue
+ priority:kEventPriorityStandard];
+ STAssertErr(status, eventAlreadyPostedErr, @"status: %ld", status);
+ EventTypeSpec types = { kTestClass, kTestKind };
+ status = FlushEventsMatchingListFromQueue(eventQueue, 1, &types);
+ STAssertNoErr(status, @"status: %ld", status);
+
+ eventQueue = GetCurrentEventQueue();
+ [event_ postToCurrentQueue];
+ status = [event_ postToQueue:eventQueue priority:kEventPriorityStandard];
+ STAssertErr(status, eventAlreadyPostedErr, @"status: %ld", status);
+ status = FlushEventsMatchingListFromQueue(eventQueue, 1, &types);
+ STAssertNoErr(status, @"status: %ld", status);
+}
+
+- (void)testPostToMainQueue {
+ [self testPostToQueue];
+}
+
+- (void)testPostToCurrentQueue {
+ STAssertEquals(GetCurrentEventQueue(), GetMainEventQueue(), nil);
+ [self testPostToMainQueue];
+}
+
+- (void)testDescription {
+ NSString *descString
+ = [NSString stringWithFormat:@"GTMCarbonEvent 'foo ' %d", kTestKind];
+ STAssertEqualObjects([event_ description], descString, nil);
+}
+@end
+
+@implementation GTMCarbonEventHandlerTest
+
+- (void)setUp {
+ handler_ = [[GTMCarbonEventHandler alloc] init];
+}
+
+- (void)tearDown {
+ [handler_ release];
+}
+
+- (void)testEventTarget {
+ STAssertNULL([handler_ eventTarget], nil);
+}
+
+- (void)testEventHandler {
+ [GTMUnitTestDevLog expectPattern:
+ @"DebugAssert: GoogleToolboxForMac: event CantUseParams .*"];
+ STAssertErr([handler_ handleEvent:nil handler:nil], eventNotHandledErr, nil);
+}
+
+- (void)testDelegate {
+ [handler_ setDelegate:self];
+ STAssertEqualObjects([handler_ delegate], self, nil);
+ [handler_ setDelegate:nil];
+ STAssertNil([handler_ delegate], nil);
+}
+
+
+- (void)testSetDelegate {
+ [self testDelegate];
+}
+
+@end
+
+@implementation GTMCarbonEventMonitorHandlerTest
+
+- (void)testEventHandler {
+ GTMCarbonEventMonitorHandler *monitor
+ = [GTMCarbonEventMonitorHandler sharedEventMonitorHandler];
+ STAssertEquals([monitor eventTarget], GetEventMonitorTarget(), nil);
+}
+
+@end
+
+@implementation GTMCarbonEventDispatcherHandlerTest
+
+- (void)testEventHandler {
+ GTMCarbonEventDispatcherHandler *dispatcher
+ = [GTMCarbonEventDispatcherHandler sharedEventDispatcherHandler];
+ STAssertEquals([dispatcher eventTarget], GetEventDispatcherTarget(), nil);
+}
+
+- (void)hitHotKey:(id)sender {
+ hotKeyHit_ = YES;
+ [NSApp stop:self];
+}
+
+- (void)hitExceptionalHotKey:(id)sender {
+ [NSException raise:@"foo" format:@"bar"];
+}
+
+- (void)testRegisterHotKeyModifiersTargetActionWhenPressed {
+
+ // This test can't be run if the screen saver is active because the security
+ // agent blocks us from sending events via remote operations
+ if (![GTMUnitTestingUtilities isScreenSaverActive]) {
+ GTMCarbonEventDispatcherHandler *dispatcher
+ = [GTMCarbonEventDispatcherHandler sharedEventDispatcherHandler];
+ STAssertNotNil(dispatcher, @"Unable to acquire singleton");
+ UInt32 keyMods = (NSShiftKeyMask | NSControlKeyMask
+ | NSAlternateKeyMask | NSCommandKeyMask);
+ EventHotKeyRef hotKey;
+ [GTMUnitTestDevLog expectPattern:@"DebugAssert: GoogleToolboxForMac: "
+ @"newKey CantCreateKey .*"];
+ STAssertNULL([dispatcher registerHotKey:0x5
+ modifiers:keyMods
+ target:nil
+ action:nil
+ whenPressed:YES],
+ @"Shouldn't have created hotkey");
+ STAssertThrowsSpecificNamed([dispatcher registerHotKey:0x5
+ modifiers:keyMods
+ target:self
+ action:@selector(badSelector:)
+ whenPressed:YES],
+ NSException, NSInternalInconsistencyException,
+ hotKey, @"Shouldn't have created hotkey");
+ hotKey = [dispatcher registerHotKey:0x5
+ modifiers:keyMods
+ target:self
+ action:@selector(hitHotKey:)
+ whenPressed:YES];
+ STAssertNotNULL(hotKey, @"Unable to create hotkey");
+
+ hotKeyHit_ = NO;
+
+ // Post the hotkey combo to the event queue. If everything is working
+ // correctly hitHotKey: should get called, and hotKeyHit_ will be set for
+ // us. We run the event loop for a set amount of time waiting for this to
+ // happen.
+ [GTMUnitTestingUtilities postTypeCharacterEvent:'g' modifiers:keyMods];
+ NSDate* future = [NSDate dateWithTimeIntervalSinceNow:1.0f];
+ [GTMUnitTestingUtilities runUntilDate:future];
+ STAssertTrue(hotKeyHit_, @"Hot key never got fired.");
+ [dispatcher unregisterHotKey:hotKey];
+ }
+}
+
+- (void)testRegisterHotKeyModifiersTargetActionWhenPressedException {
+
+ // This test can't be run if the screen saver is active because the security
+ // agent blocks us from sending events via remote operations
+ if (![GTMUnitTestingUtilities isScreenSaverActive]) {
+ GTMCarbonEventDispatcherHandler *dispatcher
+ = [GTMCarbonEventDispatcherHandler sharedEventDispatcherHandler];
+ STAssertNotNil(dispatcher, @"Unable to acquire singleton");
+ UInt32 keyMods = (NSShiftKeyMask | NSControlKeyMask
+ | NSAlternateKeyMask | NSCommandKeyMask);
+ EventHotKeyRef hotKey = [dispatcher registerHotKey:0x5
+ modifiers:keyMods
+ target:self
+ action:@selector(hitExceptionalHotKey:)
+ whenPressed:YES];
+ STAssertTrue(hotKey != nil, @"Unable to create hotkey");
+
+ // Post the hotkey combo to the event queue. If everything is working correctly
+ // hitHotKey: should get called, and hotKeyHit_ will be set for us.
+ // We run the event loop for a set amount of time waiting for this to happen.
+ [GTMUnitTestingUtilities postTypeCharacterEvent:'g' modifiers:keyMods];
+ NSDate* future = [NSDate dateWithTimeIntervalSinceNow:1.0f];
+ [GTMUnitTestDevLog expectString:@"Exception fired in hotkey: foo (bar)"];
+ [GTMUnitTestingUtilities runUntilDate:future];
+ [dispatcher unregisterHotKey:hotKey];
+ }
+}
+
+- (void)testKeyModifiers {
+ struct {
+ NSUInteger cocoaKey_;
+ UInt32 carbonKey_;
+ } keyMap[] = {
+ { NSAlphaShiftKeyMask, alphaLock},
+ { NSShiftKeyMask, shiftKey},
+ { NSControlKeyMask, controlKey},
+ { NSAlternateKeyMask, optionKey},
+ { NSCommandKeyMask, cmdKey},
+ };
+ size_t combos = pow(2, sizeof(keyMap) / sizeof(keyMap[0]));
+ for (size_t i = 0; i < combos; i++) {
+ NSUInteger cocoaMods = 0;
+ UInt32 carbonMods = 0;
+ for (size_t j = 0; j < 32 && j < sizeof(keyMap) / sizeof(keyMap[0]); j++) {
+ if (i & 1 << j) {
+ cocoaMods |= keyMap[j].cocoaKey_;
+ carbonMods |= keyMap[j].carbonKey_;
+ }
+ }
+ STAssertEquals(GTMCocoaToCarbonKeyModifiers(cocoaMods), carbonMods, nil);
+ STAssertEquals(GTMCarbonToCocoaKeyModifiers(carbonMods), cocoaMods, nil);
+ }
+}
+
+
+@end
+