PageRenderTime 129ms CodeModel.GetById 17ms app.highlight 106ms RepoModel.GetById 1ms app.codeStats 0ms

/core/externals/google-toolbox-for-mac/Foundation/GTMNSAppleEventDescriptor+FoundationTest.m

http://macfuse.googlecode.com/
Objective C | 643 lines | 529 code | 63 blank | 51 comment | 6 complexity | 5738d6537e792434212b44e99bfdba4f MD5 | raw file
  1//
  2//  GTMNSAppleEventDescriptor+FoundationTest.m
  3//
  4//  Copyright 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
 19#import "GTMSenTestCase.h"
 20#import <Carbon/Carbon.h>
 21#import "GTMNSAppleEventDescriptor+Foundation.h"
 22#import "GTMFourCharCode.h"
 23#import "GTMUnitTestDevLog.h"
 24
 25@interface GTMNSAppleEventDescriptor_TestObject : NSObject
 26@end
 27
 28@implementation GTMNSAppleEventDescriptor_TestObject
 29
 30- (NSAppleEventDescriptor*)gtm_appleEventDescriptor {
 31  return nil;
 32}
 33
 34@end
 35
 36@interface GTMNSAppleEventDescriptor_FoundationTest : GTMTestCase {
 37  BOOL gotEvent_;
 38}
 39- (void)handleEvent:(NSAppleEventDescriptor*)event 
 40          withReply:(NSAppleEventDescriptor*)reply;
 41- (void)handleEvent:(NSAppleEventDescriptor*)event 
 42          withError:(NSAppleEventDescriptor*)reply;
 43
 44@end
 45
 46@implementation GTMNSAppleEventDescriptor_FoundationTest
 47- (void)testRegisterSelectorForTypesCount {
 48  // Weird edge casey stuff.
 49  // + (void)registerSelector:(SEL)selector 
 50  //                 forTypes:(DescType*)types count:(int)count
 51  // is tested heavily by the other NSAppleEventDescriptor+foo categories.
 52  DescType type;
 53  [NSAppleEventDescriptor gtm_registerSelector:nil 
 54                                      forTypes:&type count:1];
 55  [NSAppleEventDescriptor gtm_registerSelector:@selector(initListDescriptor) 
 56                                      forTypes:nil count:1];
 57  [NSAppleEventDescriptor gtm_registerSelector:@selector(initListDescriptor) 
 58                                      forTypes:&type count:0];
 59  // Test the duplicate case
 60  [NSAppleEventDescriptor gtm_registerSelector:@selector(initListDescriptor) 
 61                                      forTypes:&type count:1];
 62  [GTMUnitTestDevLog expectPattern:@"initListDescriptor being replaced with "
 63   "initListDescriptor exists for type: [0-9]+"];
 64  [NSAppleEventDescriptor gtm_registerSelector:@selector(initListDescriptor) 
 65                                      forTypes:&type count:1];
 66}
 67
 68- (void)testObjectValue {
 69  // - (void)testObjectValue is tested heavily by the other 
 70  // NSAppleEventDescriptor+foo categories.
 71  long data = 1;
 72  // v@#f is just a bogus descriptor type that we don't recognize.
 73  NSAppleEventDescriptor *desc 
 74    = [NSAppleEventDescriptor descriptorWithDescriptorType:'v@#f'
 75                                                     bytes:&data
 76                                                    length:sizeof(data)];
 77  id value = [desc gtm_objectValue];
 78  STAssertNil(value, nil);
 79}
 80
 81- (void)testAppleEventDescriptor {
 82  // - (NSAppleEventDescriptor*)appleEventDescriptor is tested heavily by the 
 83  // other NSAppleEventDescriptor+foo categories.
 84  NSAppleEventDescriptor *desc = [self gtm_appleEventDescriptor];
 85  STAssertNotNil(desc, nil); 
 86  STAssertEquals([desc descriptorType], (DescType)typeUnicodeText, nil);
 87}
 88
 89- (void)testDescriptorWithArrayAndArrayValue {
 90  // Test empty array
 91  NSAppleEventDescriptor *desc = [[NSArray array] gtm_appleEventDescriptor];
 92  STAssertNotNil(desc, nil);
 93  STAssertEquals([desc numberOfItems], (NSInteger)0, nil);
 94  
 95  // Complex array
 96  NSArray *array = [NSArray arrayWithObjects:
 97    [NSNumber numberWithInt:4],
 98    @"foo",
 99    [NSNumber numberWithInt:2], 
100    @"bar",
101    [NSArray arrayWithObjects:
102      @"bam",
103      [NSArray arrayWithObject:[NSNumber numberWithFloat:4.2f]],
104      nil],
105    nil];
106  STAssertNotNil(array, nil);
107  desc = [array gtm_appleEventDescriptor];
108  STAssertNotNil(desc, nil);
109  NSArray *array2 = [desc gtm_objectValue];
110  STAssertNotNil(array2, nil);
111  NSArray *array3 = [desc gtm_arrayValue];
112  STAssertNotNil(array3, nil);
113  STAssertTrue([array isEqualToArray:array2], 
114               @"array: %@\narray2: %@\ndesc: %@", 
115               [array description], [array2 description], [desc description]);
116  STAssertTrue([array2 isEqualToArray:array3], 
117               @"array: %@\narray2: %@\ndesc: %@", 
118               [array description], [array2 description], [desc description]);
119  
120  // Test a single object
121  array = [NSArray arrayWithObject:@"foo"];
122  desc = [NSAppleEventDescriptor descriptorWithString:@"foo"];
123  STAssertNotNil(desc, nil);
124  array2 = [desc gtm_arrayValue];
125  STAssertTrue([array isEqualToArray:array2], 
126               @"array: %@\narray2: %@\ndesc: %@", 
127               [array description], [array2 description], [desc description]);
128  
129  // Something that doesn't know how to register itself.
130  GTMNSAppleEventDescriptor_TestObject *obj 
131    = [[[GTMNSAppleEventDescriptor_TestObject alloc] init] autorelease];
132  [GTMUnitTestDevLog expectPattern:@"Unable to create Apple Event Descriptor for .*"];
133  desc = [[NSArray arrayWithObject:obj] gtm_appleEventDescriptor];
134  STAssertNil(desc, @"Should be nil");
135  
136  // A list containing something we don't know how to deal with
137  desc = [NSAppleEventDescriptor listDescriptor];
138  NSAppleEventDescriptor *desc2 
139    = [NSAppleEventDescriptor descriptorWithDescriptorType:'@!@#'
140                                                     bytes:&desc
141                                                    length:sizeof(desc)];
142  [GTMUnitTestDevLog expectPattern:@"Unknown type of descriptor "
143   "<NSAppleEventDescriptor: '@!@#'\\(\\$[0-9A-F]*\\$\\)>"];
144  [desc insertDescriptor:desc2 atIndex:0];
145  array = [desc gtm_objectValue];
146  STAssertEquals([array count], (NSUInteger)0, @"Should have 0 items");
147}
148
149- (void)testDescriptorWithDictionaryAndDictionaryValue {
150  // Test empty dictionary
151  NSAppleEventDescriptor *desc 
152    = [[NSDictionary dictionary] gtm_appleEventDescriptor];
153  STAssertNotNil(desc, nil);
154  STAssertEquals([desc numberOfItems], (NSInteger)0, nil);
155  
156  // Complex dictionary
157  NSDictionary *dictionary = [NSDictionary dictionaryWithObjectsAndKeys:
158    @"fooobject",
159    @"fookey",
160    @"barobject",
161    @"barkey",
162    [NSDictionary dictionaryWithObjectsAndKeys:
163      @"january",
164      [GTMFourCharCode fourCharCodeWithFourCharCode:cJanuary],
165      @"february",
166      [GTMFourCharCode fourCharCodeWithFourCharCode:cFebruary],
167      nil],
168    @"dictkey",
169    nil];
170  STAssertNotNil(dictionary, nil);
171  desc = [dictionary gtm_appleEventDescriptor];
172  STAssertNotNil(desc, nil);
173  NSDictionary *dictionary2 = [desc gtm_objectValue];
174  STAssertNotNil(dictionary2, nil);
175  NSDictionary *dictionary3 = [desc gtm_dictionaryValue];
176  STAssertNotNil(dictionary3, nil);
177  STAssertEqualObjects(dictionary, dictionary2, 
178                       @"desc: %@", [desc description]);
179  STAssertEqualObjects(dictionary2, dictionary3, 
180                       @"desc: %@", [desc description]);
181  
182  // Something that doesn't know how to register itself.
183  GTMNSAppleEventDescriptor_TestObject *obj 
184    = [[[GTMNSAppleEventDescriptor_TestObject alloc] init] autorelease];
185  [GTMUnitTestDevLog expectPattern:@"Unable to create Apple Event Descriptor for .*"];
186  desc = [[NSDictionary dictionaryWithObject:obj 
187                                      forKey:@"foo"] gtm_appleEventDescriptor];
188  STAssertNil(desc, @"Should be nil");
189
190  GTMFourCharCode *fcc = [GTMFourCharCode fourCharCodeWithFourCharCode:cJanuary];
191  desc = [[NSDictionary dictionaryWithObject:obj 
192                                      forKey:fcc] gtm_appleEventDescriptor];
193  STAssertNil(desc, @"Should be nil");
194  
195  // A list containing something we don't know how to deal with
196  desc = [NSAppleEventDescriptor recordDescriptor];
197  NSAppleEventDescriptor *desc2 
198    = [NSAppleEventDescriptor descriptorWithDescriptorType:'@!@#'
199                                                     bytes:&desc
200                                                    length:sizeof(desc)];
201  [desc setDescriptor:desc2 forKeyword:cJanuary];
202  [GTMUnitTestDevLog expectPattern:@"Unknown type of descriptor "
203   "<NSAppleEventDescriptor: '@!@#'\\(\\$[0-9A-F]+\\$\\)>"];
204  dictionary = [desc gtm_objectValue];
205  STAssertEquals([dictionary count], (NSUInteger)0, @"Should have 0 items");
206  
207  // A bad dictionary 
208  dictionary = [NSDictionary dictionaryWithObjectsAndKeys:
209    @"foo",
210    [GTMFourCharCode fourCharCodeWithFourCharCode:'APPL'],
211    @"bam", 
212    @"bar",
213    nil];
214  STAssertNotNil(dictionary, nil);
215  // I cannot use expectString here to the exact string because interestingly
216  // dictionaries in 64 bit enumerate in a different order from dictionaries
217  // on 32 bit. This is the closest pattern I can match.
218  [GTMUnitTestDevLog expectPattern:@"Keys must be homogenous .*"];
219  desc = [dictionary gtm_appleEventDescriptor];
220  STAssertNil(desc, nil);
221 
222  // Another bad dictionary 
223  dictionary = [NSDictionary dictionaryWithObjectsAndKeys:
224                @"foo",
225                [NSNumber numberWithInt:4],
226                @"bam", 
227                @"bar",
228                nil];
229  STAssertNotNil(dictionary, nil);
230  // I cannot use expectString here to the exact string because interestingly
231  // dictionaries in 64 bit enumerate in a different order from dictionaries
232  // on 32 bit. This is the closest pattern I can match.
233  [GTMUnitTestDevLog expectPattern:@"Keys must be .*"];
234  desc = [dictionary gtm_appleEventDescriptor];
235  STAssertNil(desc, nil);
236  
237  // A bad descriptor
238  desc = [NSAppleEventDescriptor recordDescriptor];
239  STAssertNotNil(desc, @"");
240  NSArray *array = [NSArray arrayWithObjects:@"foo", @"bar", @"bam", nil];
241  STAssertNotNil(array, @"");
242  NSAppleEventDescriptor *userRecord = [array gtm_appleEventDescriptor];
243  STAssertNotNil(userRecord, @"");
244  [desc setDescriptor:userRecord forKeyword:keyASUserRecordFields];
245  [GTMUnitTestDevLog expectPattern:@"Got a key bam with no value in \\(.*"];
246  dictionary = [desc gtm_objectValue];
247  STAssertNil(dictionary, @"Should be nil");
248}
249
250- (void)testDescriptorWithNull {  
251  // Test Null
252  NSNull *null = [NSNull null];
253  NSAppleEventDescriptor *desc = [null gtm_appleEventDescriptor];
254  STAssertNotNil(desc, nil);
255  NSNull *null2 = [desc gtm_objectValue];
256  STAssertNotNil(null2, nil);
257  NSNull *null3 = [desc gtm_nullValue];
258  STAssertNotNil(null2, nil);
259  STAssertEqualObjects(null, null2, 
260               @"null: %@\null2: %@\ndesc: %@", 
261               [null description], [null2 description], 
262               [desc description]);
263  STAssertEqualObjects(null, null3, 
264                       @"null: %@\null3: %@\ndesc: %@", 
265                       [null description], [null3 description], 
266                       [desc description]);
267}
268
269- (void)testDescriptorWithString {
270  // Test empty String
271  NSAppleEventDescriptor *desc = [[NSString string] gtm_appleEventDescriptor];
272  STAssertNotNil(desc, nil);
273  
274  // Test String
275  NSString *string = @"Ratatouille!";
276  desc = [string gtm_appleEventDescriptor];
277  STAssertNotNil(desc, nil);
278  NSString *string2 = [desc gtm_objectValue];
279  STAssertNotNil(string2, nil);
280  STAssertEqualObjects(string, string2, 
281               @"string: %@\nstring: %@\ndesc: %@", 
282               [string description], [string2 description], [desc description]);
283  
284}
285
286- (void)testDescriptorWithNumberAndNumberValue {
287  // There's really no good way to make this into a loop sadly due
288  // to me having to pass a pointer of bytes to NSInvocation as an argument.
289  // I want the compiler to convert my int to the appropriate type.
290  
291  NSNumber *original = [NSNumber numberWithBool:YES];
292  STAssertNotNil(original, @"Value: YES");
293  NSAppleEventDescriptor *desc = [original gtm_appleEventDescriptor]; 
294  STAssertNotNil(desc, @"Value: YES");
295  id returned = [desc gtm_objectValue];
296  STAssertNotNil(returned, @"Value: YES");
297  STAssertTrue([returned isKindOfClass:[NSNumber class]], @"Value: YES");
298  STAssertEqualObjects(original, returned, @"Value: YES");
299  desc = [desc coerceToDescriptorType:typeBoolean];
300  NSNumber *number = [desc gtm_numberValue];
301  STAssertEqualObjects(number, original, @"Value: YES");
302  
303  original = [NSNumber numberWithBool:NO];
304  STAssertNotNil(original, @"Value: NO");
305  desc = [original gtm_appleEventDescriptor]; 
306  STAssertNotNil(desc, @"Value: NO");
307  returned = [desc gtm_objectValue];
308  STAssertNotNil(returned, @"Value: NO");
309  STAssertTrue([returned isKindOfClass:[NSNumber class]], @"Value: NO");
310  STAssertEqualObjects(original, returned, @"Value: NO");
311  
312  sranddev(); 
313  double value = rand();
314  
315  original = [NSNumber numberWithChar:value];
316  STAssertNotNil(original, @"Value: %g", value);
317  desc = [original gtm_appleEventDescriptor]; 
318  STAssertNotNil(desc, @"Value: %g", value);
319  returned = [desc gtm_objectValue];
320  STAssertNotNil(returned, @"Value: %g", value);
321  STAssertTrue([returned isKindOfClass:[NSNumber class]], @"Value: %g", value);
322  STAssertEqualObjects(original, returned, @"Value: %g", value);
323
324  value = rand();
325  original = [NSNumber numberWithUnsignedChar:value];
326  STAssertNotNil(original, @"Value: %g", value);
327  desc = [original gtm_appleEventDescriptor];
328  STAssertNotNil(desc, @"Value: %g", value);
329  returned = [desc gtm_objectValue];
330  STAssertNotNil(returned, @"Value: %g", value);
331  STAssertTrue([returned isKindOfClass:[NSNumber class]], @"Value: %g", value);
332  STAssertEqualObjects(original, returned, @"Value: %g", value);
333
334  value = rand();
335  original = [NSNumber numberWithShort:value];
336  STAssertNotNil(original, @"Value: %g", value);
337  desc = [original gtm_appleEventDescriptor];
338  STAssertNotNil(desc, @"Value: %g", value);
339  returned = [desc gtm_objectValue];
340  STAssertNotNil(returned, @"Value: %g", value);
341  STAssertTrue([returned isKindOfClass:[NSNumber class]], @"Value: %g", value);
342  STAssertEqualObjects(original, returned, @"Value: %g", value);
343  
344  value = rand();
345  original = [NSNumber numberWithUnsignedShort:value];
346  STAssertNotNil(original, @"Value: %g", value);
347  desc = [original gtm_appleEventDescriptor];
348  STAssertNotNil(desc, @"Value: %g", value);
349  returned = [desc gtm_objectValue];
350  STAssertNotNil(returned, @"Value: %g", value);
351  STAssertTrue([returned isKindOfClass:[NSNumber class]], @"Value: %g", value);
352  STAssertEqualObjects(original, returned, @"Value: %g", value);
353  
354  value = rand();
355  original = [NSNumber numberWithInt:(int)value];
356  STAssertNotNil(original, @"Value: %g", value);
357  desc = [original gtm_appleEventDescriptor];
358  STAssertNotNil(desc, @"Value: %g", value);
359  returned = [desc gtm_objectValue];
360  STAssertNotNil(returned, @"Value: %g", value);
361  STAssertTrue([returned isKindOfClass:[NSNumber class]], @"Value: %g", value);
362  STAssertEqualObjects(original, returned, @"Value: %g", value);
363  
364  value = rand();
365  original = [NSNumber numberWithUnsignedInt:(unsigned int)value];
366  STAssertNotNil(original, @"Value: %g", value);
367  desc = [original gtm_appleEventDescriptor];
368  STAssertNotNil(desc, @"Value: %g", value);
369  returned = [desc gtm_objectValue];
370  STAssertNotNil(returned, @"Value: %g", value);
371  STAssertTrue([returned isKindOfClass:[NSNumber class]], @"Value: %g", value);
372  STAssertEqualObjects(original, returned, @"Value: %g", value);
373  
374  value = rand();
375  original = [NSNumber numberWithLong:value];
376  STAssertNotNil(original, @"Value: %g", value);
377  desc = [original gtm_appleEventDescriptor];
378  STAssertNotNil(desc, @"Value: %g", value);
379  returned = [desc gtm_objectValue];
380  STAssertNotNil(returned, @"Value: %g", value);
381  STAssertTrue([returned isKindOfClass:[NSNumber class]], @"Value: %g", value);
382  STAssertEqualObjects(original, returned, @"Value: %g", value);
383  
384  value = rand();
385  original = [NSNumber numberWithUnsignedLong:value];
386  STAssertNotNil(original, @"Value: %g", value);
387  desc = [original gtm_appleEventDescriptor];
388  STAssertNotNil(desc, @"Value: %g", value);
389  returned = [desc gtm_objectValue];
390  STAssertNotNil(returned, @"Value: %g", value);
391  STAssertTrue([returned isKindOfClass:[NSNumber class]], @"Value: %g", value);
392  STAssertEqualObjects(original, returned, @"Value: %g", value);
393  
394  value = rand();
395  original = [NSNumber numberWithLongLong:value];
396  STAssertNotNil(original, @"Value: %g", value);
397  desc = [original gtm_appleEventDescriptor];
398  STAssertNotNil(desc, @"Value: %g", value);
399  returned = [desc gtm_objectValue];
400  STAssertNotNil(returned, @"Value: %g", value);
401  STAssertTrue([returned isKindOfClass:[NSNumber class]], @"Value: %g", value);
402  STAssertEqualObjects(original, returned, @"Value: %g", value);
403  
404  value = rand();
405  original = [NSNumber numberWithUnsignedLongLong:value];
406  STAssertNotNil(original, @"Value: %g", value);
407  desc = [original gtm_appleEventDescriptor];
408  STAssertNotNil(desc, @"Value: %g", value);
409  returned = [desc gtm_objectValue];
410  STAssertNotNil(returned, @"Value: %g", value);
411  STAssertTrue([returned isKindOfClass:[NSNumber class]], @"Value: %g", value);
412  STAssertEqualObjects(original, returned, @"Value: %g", value);
413  
414  float floatA = rand();
415  float floatB = rand();
416  value = floatA / floatB;
417  original = [NSNumber numberWithFloat:(float)value];
418  STAssertNotNil(original, @"Value: %g", value);
419  desc = [original gtm_appleEventDescriptor];
420  STAssertNotNil(desc, @"Value: %g", value);
421  returned = [desc gtm_objectValue];
422  STAssertNotNil(returned, @"Value: %g", value);
423  STAssertTrue([returned isKindOfClass:[NSNumber class]], @"Value: %g", value);
424  STAssertEqualObjects(original, returned, @"Value: %g", value);
425
426  double doubleA = rand();
427  double doubleB = rand();
428  value = doubleA / doubleB;
429  original = [NSNumber numberWithDouble:value];
430  STAssertNotNil(original, @"Value: %g", value);
431  desc = [original gtm_appleEventDescriptor];
432  STAssertNotNil(desc, @"Value: %g", value);
433  returned = [desc gtm_objectValue];
434  STAssertNotNil(returned, @"Value: %g", value);
435  STAssertTrue([returned isKindOfClass:[NSNumber class]], @"Value: %g", value);
436  STAssertEqualObjects(original, returned, @"Value: %g", value);
437
438  value = rand();
439  original = [NSNumber numberWithBool:value];
440  STAssertNotNil(original, @"Value: %g", value);
441  desc = [original gtm_appleEventDescriptor];
442  STAssertNotNil(desc, @"Value: %g", value);
443  returned = [desc gtm_objectValue];
444  STAssertNotNil(returned, @"Value: %g", value);
445  STAssertTrue([returned isKindOfClass:[NSNumber class]], @"Value: %g", value);
446  STAssertEqualObjects(original, returned, @"Value: %g", value);
447  
448  value = NAN;
449  original = [NSNumber numberWithDouble:value];
450  STAssertNotNil(original, @"Value: %g", value);
451  desc = [original gtm_appleEventDescriptor];
452  STAssertNotNil(desc, @"Value: %g", value);
453  returned = [desc gtm_objectValue];
454  STAssertNotNil(returned, @"Value: %g", value);
455  STAssertTrue([returned isKindOfClass:[NSNumber class]], @"Value: %g", value);
456  STAssertEqualObjects(original, returned, @"Value: %g", value);
457
458  value = INFINITY;
459  original = [NSNumber numberWithDouble:value];
460  STAssertNotNil(original, @"Value: %g", value);
461  desc = [original gtm_appleEventDescriptor];
462  STAssertNotNil(desc, @"Value: %g", value);
463  returned = [desc gtm_objectValue];
464  STAssertNotNil(returned, @"Value: %g", value);
465  STAssertTrue([returned isKindOfClass:[NSNumber class]], @"Value: %g", value);
466  STAssertEqualObjects(original, returned, @"Value: %g", value);
467 
468  value = -0.0;
469  original = [NSNumber numberWithDouble:value];
470  STAssertNotNil(original, @"Value: %g", value);
471  desc = [original gtm_appleEventDescriptor];
472  STAssertNotNil(desc, @"Value: %g", value);
473  returned = [desc gtm_objectValue];
474  STAssertNotNil(returned, @"Value: %g", value);
475  STAssertTrue([returned isKindOfClass:[NSNumber class]], @"Value: %g", value);
476  STAssertEqualObjects(original, returned, @"Value: %g", value);
477
478  value = -INFINITY;
479  original = [NSNumber numberWithDouble:value];
480  STAssertNotNil(original, @"Value: %g", value);
481  desc = [original gtm_appleEventDescriptor];
482  STAssertNotNil(desc, @"Value: %g", value);
483  returned = [desc gtm_objectValue];
484  STAssertNotNil(returned, @"Value: %g", value);
485  STAssertTrue([returned isKindOfClass:[NSNumber class]], @"Value: %g", value);
486  STAssertEqualObjects(original, returned, @"Value: %g", value);
487}
488
489- (void)testDescriptorWithDoubleAndDoubleValue {
490  sranddev(); 
491  for (int i = 0; i < 1000; ++i) {
492    double value1 = rand();
493    double value2 = rand();
494    double value = value1 / value2;
495    NSAppleEventDescriptor *desc 
496      = [NSAppleEventDescriptor gtm_descriptorWithDouble:value];
497    STAssertNotNil(desc, @"Value: %g", value);
498    double returnedValue = [desc gtm_doubleValue];
499    STAssertEquals(value, returnedValue, @"Value: %g", value);
500  }
501  
502  double specialCases[] = { 0.0f, __DBL_MIN__, __DBL_EPSILON__, INFINITY, NAN };
503  for (size_t i = 0; i < sizeof(specialCases) / sizeof(double); ++i) {
504    double value = specialCases[i];
505    NSAppleEventDescriptor *desc 
506      = [NSAppleEventDescriptor gtm_descriptorWithDouble:value];
507    STAssertNotNil(desc, @"Value: %g", value);
508    double returnedValue = [desc gtm_doubleValue];
509    STAssertEquals(value, returnedValue, @"Value: %g", value);
510  }
511}
512
513- (void)testDescriptorWithFloatAndFloatValue {
514  sranddev(); 
515  for (int i = 0; i < 1000; ++i) {
516    float value1 = rand();
517    float value2 = rand();
518    float value = value1 / value2;
519    NSAppleEventDescriptor *desc 
520      = [NSAppleEventDescriptor gtm_descriptorWithFloat:value];
521    STAssertNotNil(desc, @"Value: %f", value);
522    float returnedValue = [desc gtm_floatValue];
523    STAssertEquals(value, returnedValue, @"Value: %f", value);
524  }
525  
526  float specialCases[] = { 0.0f, FLT_MIN, FLT_MAX, FLT_EPSILON, INFINITY, NAN };
527  for (size_t i = 0; i < sizeof(specialCases) / sizeof(float); ++i) {
528    float value = specialCases[i];
529    NSAppleEventDescriptor *desc 
530      = [NSAppleEventDescriptor gtm_descriptorWithFloat:value];
531    STAssertNotNil(desc, @"Value: %f", value);
532    float returnedValue = [desc gtm_floatValue];
533    STAssertEquals(value, returnedValue, @"Value: %f", value);
534  }
535}
536
537- (void)testDescriptorWithCGFloatAndCGFloatValue {
538  sranddev(); 
539  for (int i = 0; i < 1000; ++i) {
540    CGFloat value1 = rand();
541    CGFloat value2 = rand();
542    CGFloat value = value1 / value2;
543    NSAppleEventDescriptor *desc 
544      = [NSAppleEventDescriptor gtm_descriptorWithCGFloat:value];
545    STAssertNotNil(desc, @"Value: %g", (double)value);
546    CGFloat returnedValue = [desc gtm_cgFloatValue];
547    STAssertEquals(value, returnedValue, @"Value: %g", (double)value);
548  }
549  
550  CGFloat specialCases[] = { 0.0f, CGFLOAT_MIN, CGFLOAT_MAX, NAN };
551  for (size_t i = 0; i < sizeof(specialCases) / sizeof(CGFloat); ++i) {
552    CGFloat value = specialCases[i];
553    NSAppleEventDescriptor *desc 
554      = [NSAppleEventDescriptor gtm_descriptorWithCGFloat:value];
555    STAssertNotNil(desc, @"Value: %g", (double)value);
556    CGFloat returnedValue = [desc gtm_cgFloatValue];
557    STAssertEquals(value, returnedValue, @"Value: %g", (double)value);
558  }
559}
560
561- (void)testDescriptorWithGTMFourCharCode {
562  GTMFourCharCode *fcc = [GTMFourCharCode fourCharCodeWithFourCharCode:'APPL'];
563  STAssertNotNil(fcc, nil);
564  NSAppleEventDescriptor *desc = [fcc gtm_appleEventDescriptor];
565  STAssertNotNil(desc, nil);
566  GTMFourCharCode *fcc2 = [desc gtm_objectValue];
567  STAssertNotNil(fcc2, nil);
568  STAssertEqualObjects(fcc, fcc2, nil);
569  STAssertEquals([desc descriptorType], (DescType)typeType, nil);
570  desc = [fcc gtm_appleEventDescriptorOfType:typeKeyword];
571  STAssertNotNil(desc, nil);
572  fcc2 = [desc gtm_objectValue];
573  STAssertNotNil(fcc2, nil);
574  STAssertEqualObjects(fcc, fcc2, nil);
575  STAssertEquals([desc descriptorType], (DescType)typeKeyword, nil);
576}
577
578- (void)testDescriptorWithDescriptor {
579  NSAppleEventDescriptor *desc
580    = [NSAppleEventDescriptor descriptorWithString:@"foo"];
581  NSAppleEventDescriptor *desc2 = [desc gtm_appleEventDescriptor];
582  STAssertEqualObjects(desc, desc2, nil);
583}
584
585- (void)handleEvent:(NSAppleEventDescriptor*)event 
586          withReply:(NSAppleEventDescriptor*)reply {
587  gotEvent_ = YES;
588  NSAppleEventDescriptor *answer = [NSAppleEventDescriptor descriptorWithInt32:1];
589  [reply setDescriptor:answer forKeyword:keyDirectObject];
590}
591
592- (void)handleEvent:(NSAppleEventDescriptor*)event 
593          withError:(NSAppleEventDescriptor*)error {
594  gotEvent_ = YES;
595  NSAppleEventDescriptor *answer = [NSAppleEventDescriptor descriptorWithInt32:1];
596  [error setDescriptor:answer forKeyword:keyErrorNumber];
597}
598
599- (void)testSend {
600  const AEEventClass eventClass = 'Fooz';
601  const AEEventID eventID = 'Ball';
602  NSAppleEventManager *mgr = [NSAppleEventManager sharedAppleEventManager];
603  [mgr setEventHandler:self 
604           andSelector:@selector(handleEvent:withReply:)
605         forEventClass:eventClass 
606            andEventID:'Ball'];
607  NSAppleEventDescriptor *currentProcess 
608    = [[NSProcessInfo processInfo] gtm_appleEventDescriptor];
609  NSAppleEventDescriptor *event 
610    = [NSAppleEventDescriptor appleEventWithEventClass:eventClass
611                                               eventID:eventID
612                                      targetDescriptor:currentProcess
613                                              returnID:kAutoGenerateReturnID
614                                         transactionID:kAnyTransactionID];
615  gotEvent_ = NO;
616  NSAppleEventDescriptor *reply;
617  BOOL goodEvent = [event gtm_sendEventWithMode:kAEWaitReply timeOut:60 reply:&reply];
618  [mgr removeEventHandlerForEventClass:eventClass andEventID:eventID];
619  STAssertTrue(goodEvent, @"bad event?");
620  STAssertTrue(gotEvent_, @"Handler not called");
621  NSAppleEventDescriptor *value = [reply descriptorForKeyword:keyDirectObject];
622  STAssertEquals([value int32Value], (SInt32)1, @"didn't get reply");
623  
624  
625  gotEvent_ = NO;
626  [GTMUnitTestDevLog expectString:@"Unable to send message: "
627   "<NSAppleEventDescriptor: 'Fooz'\\'Ball'{  }> -1708"];
628  goodEvent = [event gtm_sendEventWithMode:kAEWaitReply timeOut:60 reply:&reply];
629  STAssertFalse(goodEvent, @"good event?");
630  STAssertFalse(gotEvent_, @"Handler called?");
631  
632  [mgr setEventHandler:self 
633           andSelector:@selector(handleEvent:withError:)
634         forEventClass:eventClass 
635            andEventID:eventID];
636  gotEvent_ = NO;
637  goodEvent = [event gtm_sendEventWithMode:kAEWaitReply timeOut:60 reply:&reply];
638  STAssertFalse(goodEvent, @"good event?");
639  STAssertTrue(gotEvent_, @"Handler not called?");
640  [mgr removeEventHandlerForEventClass:eventClass andEventID:eventID];
641}
642
643@end