/core/externals/update-engine/externals/google-toolbox-for-mac/Foundation/GTMNSAppleScript+HandlerTest.m

http://macfuse.googlecode.com/ · Objective C · 504 lines · 410 code · 47 blank · 47 comment · 3 complexity · 97245ab7590cf15a0374a6a9e901c564 MD5 · raw file

  1. //
  2. // GTMNSAppleScript+HandlerTest.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. #import "GTMSenTestCase.h"
  19. #import <Carbon/Carbon.h>
  20. #import "GTMNSAppleScript+Handler.h"
  21. #import "GTMNSAppleEventDescriptor+Foundation.h"
  22. #import "GTMUnitTestDevLog.h"
  23. #import "GTMSystemVersion.h"
  24. #import "GTMFourCharCode.h"
  25. @protocol ScriptInterface
  26. - (id)test;
  27. - (id)testReturnParam:(id)param;
  28. - (id)testAddParams:(id)param1 :(id)param2;
  29. @end
  30. @interface GTMNSAppleScript_HandlerTest : GTMTestCase {
  31. NSAppleScript *script_;
  32. }
  33. @end
  34. @implementation GTMNSAppleScript_HandlerTest
  35. - (void)setUp {
  36. NSBundle *bundle
  37. = [NSBundle bundleForClass:[GTMNSAppleScript_HandlerTest class]];
  38. STAssertNotNil(bundle, nil);
  39. NSString *path = [bundle pathForResource:@"GTMNSAppleEvent+HandlerTest"
  40. ofType:@"scpt"
  41. inDirectory:@"Scripts"];
  42. STAssertNotNil(path, [bundle description]);
  43. NSDictionary *error = nil;
  44. script_
  45. = [[NSAppleScript alloc] initWithContentsOfURL:[NSURL fileURLWithPath:path]
  46. error:&error];
  47. STAssertNotNil(script_, [error description]);
  48. STAssertNil(error, @"Error should be nil. Error = %@", [error description]);
  49. }
  50. - (void)tearDown {
  51. [script_ release];
  52. script_ = nil;
  53. }
  54. - (void)testExecuteAppleEvent {
  55. NSString *source = @"on test()\nreturn 1\nend test";
  56. NSAppleScript *script
  57. = [[[NSAppleScript alloc] initWithSource:source] autorelease];
  58. STAssertNotNil(script, nil);
  59. NSDictionary *error = nil;
  60. NSAppleEventDescriptor *desc = [script gtm_executePositionalHandler:@"test"
  61. parameters:nil
  62. error:&error];
  63. STAssertNotNil(desc, [error description]);
  64. STAssertNil(error, @"Error should be nil. Error = %@", [error description]);
  65. STAssertEquals([desc gtm_objectValue], [NSNumber numberWithInt:1], nil);
  66. // bogus script
  67. source = @"adf872345ba asdf asdf gr";
  68. script = [[[NSAppleScript alloc] initWithSource:source] autorelease];
  69. STAssertNotNil(script, nil);
  70. desc = [script gtm_executePositionalHandler:@"test"
  71. parameters:nil
  72. error:&error];
  73. STAssertNil(desc, nil);
  74. STAssertNotNil(error, @"Error should not be nil");
  75. }
  76. - (void)testHandlerNoParamsNoReturn {
  77. NSDictionary *error = nil;
  78. NSAppleEventDescriptor *desc = [script_ gtm_executePositionalHandler:@"test"
  79. parameters:nil
  80. error:&error];
  81. STAssertNotNil(desc, [error description]);
  82. STAssertNil(error, @"Error should be nil. Error = %@", [error description]);
  83. STAssertEquals([desc descriptorType], (DescType)typeNull, nil);
  84. desc = [script_ gtm_executePositionalHandler:@"test"
  85. parameters:[NSArray array]
  86. error:&error];
  87. STAssertNotNil(desc, [error description]);
  88. STAssertNil(error, @"Error should be nil. Error = %@", [error description]);
  89. STAssertEquals([desc descriptorType], (DescType)typeNull, nil);
  90. //Applescript doesn't appear to get upset about extra params
  91. desc = [script_ gtm_executePositionalHandler:@"test"
  92. parameters:[NSArray arrayWithObject:@"foo"]
  93. error:&error];
  94. STAssertNotNil(desc, [error description]);
  95. STAssertNil(error, @"Error should be nil. Error = %@", [error description]);
  96. STAssertEquals([desc descriptorType], (DescType)typeNull, nil);
  97. }
  98. - (void)testHandlerNoParamsWithReturn {
  99. NSDictionary *error = nil;
  100. NSAppleEventDescriptor *desc
  101. = [script_ gtm_executePositionalHandler:@"testReturnOne"
  102. parameters:nil
  103. error:&error];
  104. STAssertNotNil(desc, [error description]);
  105. STAssertNil(error, @"Error should be nil. Error = %@", [error description]);
  106. STAssertEquals([desc descriptorType], (DescType)typeSInt32, nil);
  107. STAssertEquals([desc int32Value], (SInt32)1, nil);
  108. desc = [script_ gtm_executePositionalHandler:@"testReturnOne"
  109. parameters:[NSArray array]
  110. error:&error];
  111. STAssertNotNil(desc, [error description]);
  112. STAssertNil(error, @"Error should be nil. Error = %@", [error description]);
  113. STAssertEquals([desc descriptorType], (DescType)typeSInt32, nil);
  114. STAssertEquals([desc int32Value], (SInt32)1, nil);
  115. //Applescript doesn't appear to get upset about extra params
  116. desc = [script_ gtm_executePositionalHandler:@"testReturnOne"
  117. parameters:[NSArray arrayWithObject:@"foo"]
  118. error:&error];
  119. STAssertNotNil(desc, [error description]);
  120. STAssertNil(error, @"Error should be nil. Error = %@", [error description]);
  121. STAssertEquals([desc descriptorType], (DescType)typeSInt32, nil);
  122. STAssertEquals([desc int32Value], (SInt32)1, nil);
  123. }
  124. - (void)testHandlerOneParamWithReturn {
  125. NSDictionary *error = nil;
  126. // Note case change in executeHandler call
  127. NSAppleEventDescriptor *desc
  128. = [script_ gtm_executePositionalHandler:@"testreturnParam"
  129. parameters:nil
  130. error:&error];
  131. STAssertNil(desc, @"Desc should by nil %@", desc);
  132. STAssertNotNil(error, nil);
  133. error = nil;
  134. desc = [script_ gtm_executePositionalHandler:@"testReturnParam"
  135. parameters:[NSArray array]
  136. error:&error];
  137. STAssertNil(desc, @"Desc should by nil %@", desc);
  138. // Verify that our error handling is working correctly.
  139. STAssertEquals([[error allKeys] count], (NSUInteger)6, @"%@", error);
  140. STAssertNotNil([error objectForKey:GTMNSAppleScriptErrorOffendingObject],
  141. @"%@", error);
  142. STAssertNotNil([error objectForKey:GTMNSAppleScriptErrorPartialResult],
  143. @"%@", error);
  144. error = nil;
  145. desc = [script_ gtm_executePositionalHandler:@"testReturnParam"
  146. parameters:[NSArray arrayWithObject:@"foo"]
  147. error:&error];
  148. STAssertNotNil(desc, [error description]);
  149. STAssertNil(error, @"Error should be nil. Error = %@", [error description]);
  150. STAssertEquals([desc descriptorType], (DescType)typeUnicodeText, nil);
  151. STAssertEqualObjects([desc gtm_objectValue], @"foo", nil);
  152. }
  153. - (void)testHandlerTwoParamsWithReturn {
  154. NSDictionary *error = nil;
  155. // Note case change in executeHandler call
  156. // Test case and empty params
  157. NSAppleEventDescriptor *desc
  158. = [script_ gtm_executePositionalHandler:@"testADDPArams"
  159. parameters:nil
  160. error:&error];
  161. STAssertNil(desc, @"Desc should by nil %@", desc);
  162. STAssertNotNil(error, nil);
  163. // Test empty params
  164. error = nil;
  165. desc = [script_ gtm_executePositionalHandler:@"testAddParams"
  166. parameters:[NSArray array]
  167. error:&error];
  168. STAssertNil(desc, @"Desc should by nil %@", desc);
  169. STAssertNotNil(error, nil);
  170. error = nil;
  171. NSArray *args = [NSArray arrayWithObjects:
  172. [NSNumber numberWithInt:1],
  173. [NSNumber numberWithInt:2],
  174. nil];
  175. desc = [script_ gtm_executePositionalHandler:@"testAddParams"
  176. parameters:args
  177. error:&error];
  178. STAssertNotNil(desc, [error description]);
  179. STAssertNil(error, @"Error should be nil. Error = %@", [error description]);
  180. STAssertEquals([desc descriptorType], (DescType)typeSInt32, nil);
  181. STAssertEquals([desc int32Value], (SInt32)3, nil);
  182. // Test bad params
  183. error = nil;
  184. args = [NSArray arrayWithObjects:
  185. @"foo",
  186. @"bar",
  187. nil];
  188. desc = [script_ gtm_executePositionalHandler:@"testAddParams"
  189. parameters:args
  190. error:&error];
  191. STAssertNil(desc, @"Desc should by nil %@", desc);
  192. STAssertNotNil(error, nil);
  193. // Test too many params. Currently Applescript allows this so it should pass
  194. error = nil;
  195. args = [NSArray arrayWithObjects:
  196. [NSNumber numberWithInt:1],
  197. [NSNumber numberWithInt:2],
  198. [NSNumber numberWithInt:3],
  199. nil];
  200. desc = [script_ gtm_executePositionalHandler:@"testAddParams"
  201. parameters:args
  202. error:&error];
  203. STAssertNotNil(desc, [error description]);
  204. STAssertNil(error, @"Error should be nil. Error = %@", [error description]);
  205. STAssertEquals([desc descriptorType], (DescType)typeSInt32, nil);
  206. STAssertEquals([desc int32Value], (SInt32)3, nil);}
  207. - (void)testLabeledHandler {
  208. NSDictionary *error = nil;
  209. AEKeyword labels[] = { keyDirectObject,
  210. keyASPrepositionOnto,
  211. keyASPrepositionGiven };
  212. id params[3];
  213. params[0] = [NSNumber numberWithInt:1];
  214. params[1] = [NSNumber numberWithInt:3];
  215. params[2] = [NSDictionary dictionaryWithObject:[NSNumber numberWithInt:4]
  216. forKey:@"othervalue"];
  217. NSAppleEventDescriptor *desc
  218. = [script_ gtm_executeLabeledHandler:@"testAdd"
  219. labels:labels
  220. parameters:params
  221. count:sizeof(params) / sizeof(id)
  222. error:&error];
  223. STAssertNotNil(desc, [error description]);
  224. STAssertNil(error, @"Error should be nil. Error = %@", [error description]);
  225. STAssertEquals([desc descriptorType], (DescType)typeSInt32, nil);
  226. STAssertEquals([desc int32Value], (SInt32)8, nil);
  227. // Test too many params. Currently Applescript allows this so it should pass
  228. AEKeyword labels2[] = { keyDirectObject,
  229. keyASPrepositionOnto,
  230. keyASPrepositionBetween,
  231. keyASPrepositionGiven };
  232. id params2[4];
  233. params2[0] = [NSNumber numberWithInt:1];
  234. params2[1] = [NSNumber numberWithInt:3];
  235. params2[2] = [NSNumber numberWithInt:5];
  236. params2[3] = [NSDictionary dictionaryWithObject:[NSNumber numberWithInt:4]
  237. forKey:@"othervalue"];
  238. error = nil;
  239. desc = [script_ gtm_executeLabeledHandler:@"testAdd"
  240. labels:labels2
  241. parameters:params2
  242. count:sizeof(params2) / sizeof(id)
  243. error:&error];
  244. STAssertNotNil(desc, [error description]);
  245. STAssertNil(error, @"Error should be nil. Error = %@", [error description]);
  246. STAssertEquals([desc descriptorType], (DescType)typeSInt32, nil);
  247. STAssertEquals([desc int32Value], (SInt32)8, nil);}
  248. - (void)testHandlers {
  249. NSSet *handlers = [script_ gtm_handlers];
  250. NSSet *expected = [NSSet setWithObjects:
  251. @"aevtpdoc",
  252. @"test",
  253. @"testreturnone",
  254. @"testreturnparam",
  255. @"testaddparams",
  256. @"testadd",
  257. @"testgetscript",
  258. nil];
  259. if ([GTMSystemVersion isSnowLeopardOrGreater]) {
  260. // Workaround for bug in SnowLeopard
  261. // rdar://66688601 OSAGetHandlersNames returns names in camelcase instead
  262. // of smallcaps.
  263. handlers = [handlers valueForKey:@"lowercaseString"];
  264. }
  265. STAssertEqualObjects(handlers, expected, @"Unexpected handlers?");
  266. }
  267. - (void)testInheritedHandlers {
  268. NSDictionary *error = nil;
  269. NSAppleEventDescriptor *desc
  270. = [script_ gtm_executePositionalHandler:@"testGetScript"
  271. parameters:nil
  272. error:&error];
  273. STAssertNil(error, nil);
  274. STAssertNotNil(desc, nil);
  275. NSAppleScript *script = [desc gtm_objectValue];
  276. STAssertTrue([script isKindOfClass:[NSAppleScript class]], nil);
  277. error = nil;
  278. desc = [script gtm_executePositionalHandler:@"parentTestScriptFunc"
  279. parameters:nil error:&error];
  280. STAssertNil(error, nil);
  281. STAssertNotNil(desc, nil);
  282. NSString *value = [desc gtm_objectValue];
  283. STAssertEqualObjects(value, @"parent", nil);
  284. }
  285. - (void)testProperties {
  286. NSDictionary *error = nil;
  287. NSAppleEventDescriptor *desc
  288. = [script_ gtm_executePositionalHandler:@"testGetScript"
  289. parameters:nil
  290. error:&error];
  291. STAssertNil(error, nil);
  292. STAssertNotNil(desc, nil);
  293. NSAppleScript *script = [desc gtm_objectValue];
  294. STAssertTrue([script isKindOfClass:[NSAppleScript class]], nil);
  295. NSSet *properties = [script gtm_properties];
  296. NSSet *expected
  297. = [NSSet setWithObjects:
  298. @"testscriptproperty",
  299. @"parenttestscriptproperty",
  300. @"foo",
  301. @"testscript",
  302. @"parenttestscript",
  303. @"asdscriptuniqueidentifier",
  304. [GTMFourCharCode fourCharCodeWithFourCharCode:pVersion],
  305. [GTMFourCharCode fourCharCodeWithFourCharCode:pASPrintDepth],
  306. [GTMFourCharCode fourCharCodeWithFourCharCode:pASTopLevelScript],
  307. [GTMFourCharCode fourCharCodeWithFourCharCode:pASResult],
  308. [GTMFourCharCode fourCharCodeWithFourCharCode:pASMinutes],
  309. [GTMFourCharCode fourCharCodeWithFourCharCode:pASDays],
  310. // No constant for linefeed in the 10.5 sdk
  311. // Radar 6132775 Need a constant for the Applescript Property 'lnfd'
  312. [GTMFourCharCode fourCharCodeWithFourCharCode:'lnfd'],
  313. [GTMFourCharCode fourCharCodeWithFourCharCode:pASPi],
  314. [GTMFourCharCode fourCharCodeWithFourCharCode:pASReturn],
  315. [GTMFourCharCode fourCharCodeWithFourCharCode:pASSpace],
  316. [GTMFourCharCode fourCharCodeWithFourCharCode:pASPrintLength],
  317. [GTMFourCharCode fourCharCodeWithFourCharCode:pASQuote],
  318. [GTMFourCharCode fourCharCodeWithFourCharCode:pASWeeks],
  319. [GTMFourCharCode fourCharCodeWithFourCharCode:pTextItemDelimiters],
  320. // Applescript properties should be pASSeconds, but
  321. // on 10.5.4/10.5.5 it is actually using cSeconds.
  322. // Radar 6132696 Applescript root level property is cSeconds
  323. // instead of pASSeconds
  324. [GTMFourCharCode fourCharCodeWithFourCharCode:cSeconds],
  325. [GTMFourCharCode fourCharCodeWithFourCharCode:pASHours],
  326. [GTMFourCharCode fourCharCodeWithFourCharCode:pASTab],
  327. nil];
  328. if ([GTMSystemVersion isSnowLeopardOrGreater]) {
  329. // Workaround for bug in SnowLeopard
  330. // rdar://6289077 OSAGetPropertyNames returns names in camelcase instead
  331. // of lowercase.
  332. id obj;
  333. NSMutableSet *properties2 = [NSMutableSet set];
  334. GTM_FOREACH_OBJECT(obj, properties) {
  335. if ([obj isKindOfClass:[NSString class]]) {
  336. obj = [obj lowercaseString];
  337. }
  338. [properties2 addObject:obj];
  339. }
  340. properties = properties2;
  341. }
  342. STAssertEqualObjects(properties, expected, @"Unexpected properties?");
  343. id value = [script gtm_valueForProperty:@"testScriptProperty"];
  344. STAssertEqualObjects(value, [NSNumber numberWithInt:5], @"bad property?");
  345. BOOL goodSet = [script gtm_setValue:@"bar"
  346. forProperty:@"foo"
  347. addingDefinition:NO];
  348. STAssertTrue(goodSet, @"Couldn't set property");
  349. // Test local set
  350. value = [script gtm_valueForProperty:@"foo"];
  351. STAssertEqualObjects(value, @"bar", @"bad property?");
  352. // Test inherited set
  353. value = [script_ gtm_valueForProperty:@"foo"];
  354. STAssertEqualObjects(value, @"bar", @"bad property?");
  355. [GTMUnitTestDevLog expectPattern:@"Unable to setValue:bar forProperty:"
  356. "\\(null\\) from <NSAppleScript: 0x[0-9a-f]+> \\(-50\\)"];
  357. goodSet = [script gtm_setValue:@"bar"
  358. forProperty:nil
  359. addingDefinition:NO];
  360. STAssertFalse(goodSet, @"Set property?");
  361. [GTMUnitTestDevLog expectPattern:@"Unable to setValue:bar forProperty:3"
  362. " from <NSAppleScript: 0x[0-9a-f]+> \\(-50\\)"];
  363. goodSet = [script gtm_setValue:@"bar"
  364. forProperty:[NSNumber numberWithInt:3]
  365. addingDefinition:YES];
  366. STAssertFalse(goodSet, @"Set property?");
  367. [GTMUnitTestDevLog expectPattern:@"Unable to get valueForProperty:gargle "
  368. "from <NSAppleScript: 0x[0-9a-f]+> \\(-1753\\)"];
  369. value = [script gtm_valueForProperty:@"gargle"];
  370. STAssertNil(value, @"Property named gargle?");
  371. goodSet = [script_ gtm_setValue:@"wow"
  372. forProperty:@"addedProperty"
  373. addingDefinition:YES];
  374. STAssertTrue(goodSet, @"Unable to addProperty");
  375. value = [script gtm_valueForProperty:@"addedProperty"];
  376. STAssertNotNil(value, nil);
  377. STAssertEqualObjects(value, @"wow", nil);
  378. // http://www.straightdope.com/classics/a3_341.html
  379. NSNumber *newPI = [NSNumber numberWithInt:3];
  380. goodSet = [script gtm_setValue:newPI
  381. forPropertyEnum:pASPi
  382. addingDefinition:NO];
  383. STAssertTrue(goodSet, @"Unable to set property");
  384. value = [script_ gtm_valueForPropertyEnum:pASPi];
  385. STAssertNotNil(value, nil);
  386. STAssertEqualObjects(value, newPI, @"bad property");
  387. }
  388. - (void)testFailures {
  389. NSDictionary *error = nil;
  390. NSAppleEventDescriptor *desc
  391. = [script_ gtm_executePositionalHandler:@"noSuchTest"
  392. parameters:nil
  393. error:&error];
  394. STAssertNil(desc, nil);
  395. STAssertNotNil(error, nil);
  396. // Test with empty handler name
  397. error = nil;
  398. desc = [script_ gtm_executePositionalHandler:@""
  399. parameters:[NSArray array]
  400. error:&error];
  401. STAssertNil(desc, nil);
  402. STAssertNotNil(error, nil);
  403. // Test with nil handler
  404. error = nil;
  405. desc = [script_ gtm_executePositionalHandler:nil
  406. parameters:[NSArray array]
  407. error:&error];
  408. STAssertNil(desc, nil);
  409. STAssertNotNil(error, nil);
  410. // Test with nil handler and nil error
  411. desc = [script_ gtm_executePositionalHandler:nil
  412. parameters:nil
  413. error:nil];
  414. STAssertNil(desc, nil);
  415. // Test with a bad script
  416. NSAppleScript *script
  417. = [[[NSAppleScript alloc] initWithSource:@"david hasselhoff"] autorelease];
  418. [GTMUnitTestDevLog expectPattern:@"Unable to compile script: .*"];
  419. [GTMUnitTestDevLog expectString:@"Unable to coerce script -2147450879"];
  420. NSSet *handlers = [script gtm_handlers];
  421. STAssertEquals([handlers count], (NSUInteger)0, @"Should have no handlers");
  422. [GTMUnitTestDevLog expectPattern:@"Unable to compile script: .*"];
  423. [GTMUnitTestDevLog expectString:@"Unable to coerce script -2147450879"];
  424. NSSet *properties = [script gtm_properties];
  425. STAssertEquals([properties count],
  426. (NSUInteger)0,
  427. @"Should have no properties");
  428. [GTMUnitTestDevLog expectPattern:@"Unable to compile script: .*"];
  429. [GTMUnitTestDevLog expectString:@"Unable to get script info about "
  430. @"open handler -2147450879"];
  431. STAssertFalse([script gtm_hasOpenDocumentsHandler],
  432. @"Has an opendoc handler?");
  433. }
  434. - (void)testScriptDescriptors {
  435. NSAppleEventDescriptor *desc = [script_ gtm_appleEventDescriptor];
  436. STAssertNotNil(desc, @"Couldn't make a script desc");
  437. NSAppleScript *script = [desc gtm_objectValue];
  438. STAssertNotNil(script, @"Couldn't get a script back");
  439. NSSet *handlers = [script gtm_handlers];
  440. STAssertNotNil(handlers, @"Couldn't get handlers");
  441. }
  442. - (void)testOpenHandler {
  443. STAssertFalse([script_ gtm_hasOpenDocumentsHandler], nil);
  444. id script = [script_ gtm_valueForProperty:@"testscript"];
  445. STAssertNotNil(script, nil);
  446. STAssertTrue([script gtm_hasOpenDocumentsHandler], nil);
  447. }
  448. - (void)testForwarding {
  449. id<ScriptInterface> foo = (id<ScriptInterface>)script_;
  450. [foo test];
  451. NSNumber *val = [foo testReturnParam:[NSNumber numberWithInt:2]];
  452. STAssertEquals([val intValue], 2, @"should be 2");
  453. val = [foo testAddParams:[NSNumber numberWithInt:2]
  454. :[NSNumber numberWithInt:3]];
  455. STAssertEquals([val intValue], 5, @"should be 5");
  456. }
  457. @end