SeqTest.m 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481
  1. // Copyright 2015 The Go Authors. All rights reserved.
  2. // Use of this source code is governed by a BSD-style
  3. // license that can be found in the LICENSE file.
  4. //go:build ignore
  5. // +build ignore
  6. #import <Foundation/Foundation.h>
  7. #import <XCTest/XCTest.h>
  8. #import "testpkg/Testpkg.h"
  9. // Objective-C implementation of testpkg.I2.
  10. @interface Number : NSObject <TestpkgI2> {
  11. }
  12. @property int32_t value;
  13. // TODO(hyangah): error:error is not good.
  14. - (BOOL)error:(BOOL)e error:(NSError **)error;
  15. - (int64_t)times:(int32_t)v;
  16. @end
  17. // numI is incremented when the first numI objective-C implementation is
  18. // deallocated.
  19. static int numI = 0;
  20. @implementation Number {
  21. }
  22. @synthesize value;
  23. - (NSString *)stringError:(NSString *)s
  24. error:(NSError **)error {
  25. if ([s isEqualToString:@"number"]) {
  26. return @"OK";
  27. }
  28. *error = [NSError errorWithDomain:@"SeqTest" code:1 userInfo:@{NSLocalizedDescriptionKey: @"NumberError"}];
  29. return NULL;
  30. }
  31. - (BOOL)error:(BOOL)triggerError error:(NSError **)error {
  32. if (!triggerError) {
  33. return YES;
  34. }
  35. if (error != NULL) {
  36. *error = [NSError errorWithDomain:@"SeqTest" code:1 userInfo:NULL];
  37. }
  38. return NO;
  39. }
  40. - (int64_t)times:(int32_t)v {
  41. return v * value;
  42. }
  43. - (void)dealloc {
  44. if (self.value == 0) {
  45. numI++;
  46. }
  47. }
  48. @end
  49. // Objective-C implementation of testpkg.NullTest.
  50. @interface NullTest : NSObject <TestpkgNullTest> {
  51. }
  52. - (TestpkgNullTest *)null;
  53. @end
  54. @implementation NullTest {
  55. }
  56. - (TestpkgNullTest *)null {
  57. return nil;
  58. }
  59. @end
  60. // Objective-C implementation of testpkg.InterfaceDupper.
  61. @interface IDup : NSObject <TestpkgInterfaceDupper> {
  62. }
  63. @end
  64. @implementation IDup {
  65. }
  66. - (id<TestpkgInterface>)iDup:(id<TestpkgInterface>)i {
  67. return i;
  68. }
  69. @end
  70. // Objective-C implementation of testpkg.ConcreteDupper.
  71. @interface CDup : NSObject <TestpkgConcreteDupper> {
  72. }
  73. @end
  74. @implementation CDup {
  75. }
  76. - (TestpkgConcrete *)cDup:(TestpkgConcrete *)c {
  77. return c;
  78. }
  79. @end
  80. // Objective-C implementation of testpkg.EmptyThrower.
  81. @interface EmptyErrorer: NSObject <TestpkgEmptyErrorer> {
  82. }
  83. @end
  84. @implementation EmptyErrorer {
  85. }
  86. - (BOOL)emptyError:(NSError **)error {
  87. *error = [NSError errorWithDomain:@"SeqTest" code:1 userInfo:NULL];
  88. return NO;
  89. }
  90. @end
  91. @interface tests : XCTestCase
  92. @end
  93. @implementation tests
  94. - (void)setUp {
  95. [super setUp];
  96. }
  97. - (void)tearDown {
  98. [super tearDown];
  99. }
  100. - (void)testBasics {
  101. TestpkgHi();
  102. TestpkgInt(42);
  103. }
  104. - (void)testAdd {
  105. int64_t sum = TestpkgAdd(31, 21);
  106. XCTAssertEqual(sum, 52, @"TestpkgSum(31, 21) = %lld, want 52\n", sum);
  107. }
  108. - (void)testHello:(NSString *)input {
  109. NSString *got = TestpkgAppendHello(input);
  110. NSString *want = [NSString stringWithFormat:@"Hello, %@!", input];
  111. XCTAssertEqualObjects(got, want, @"want %@\nTestpkgHello(%@)= %@", want, input, got);
  112. }
  113. - (void)testHellos {
  114. [self testHello:@"세계"]; // korean, utf-8, world.
  115. unichar t[] = {
  116. 0xD83D, 0xDCA9,
  117. }; // utf-16, pile of poo.
  118. [self testHello:[NSString stringWithCharacters:t length:2]];
  119. }
  120. - (void)testString {
  121. NSString *input = @"";
  122. NSString *got = TestpkgStrDup(input);
  123. XCTAssertEqualObjects(got, input, @"want %@\nTestpkgEcho(%@)= %@", input, input, got);
  124. input = @"FOO";
  125. got = TestpkgStrDup(input);
  126. XCTAssertEqualObjects(got, input, @"want %@\nTestpkgEcho(%@)= %@", input, input, got);
  127. }
  128. - (void)testStruct {
  129. TestpkgS2 *s = TestpkgNewS2(10.0, 100.0);
  130. XCTAssertNotNil(s, @"TestpkgNewS2 returned NULL");
  131. double x = [s x];
  132. double y = [s y];
  133. double sum = [s sum];
  134. XCTAssertTrue(x == 10.0 && y == 100.0 && sum == 110.0,
  135. @"TestpkgS2(10.0, 100.0).X=%f Y=%f SUM=%f; want 10, 100, 110", x, y, sum);
  136. double sum2 = TestpkgCallSSum(s);
  137. XCTAssertEqual(sum, sum2, @"TestpkgCallSSum(s)=%f; want %f as returned by s.Sum", sum2, sum);
  138. [s setX:7];
  139. [s setY:70];
  140. x = [s x];
  141. y = [s y];
  142. sum = [s sum];
  143. XCTAssertTrue(x == 7 && y == 70 && sum == 77,
  144. @"TestpkgS2(7, 70).X=%f Y=%f SUM=%f; want 7, 70, 77", x, y, sum);
  145. NSString *first = @"trytwotested";
  146. NSString *second = @"test";
  147. NSString *got = [s tryTwoStrings:first second:second];
  148. NSString *want = [first stringByAppendingString:second];
  149. XCTAssertEqualObjects(got, want, @"TestpkgS_TryTwoStrings(%@, %@)= %@; want %@", first, second, got, want);
  150. }
  151. - (void)testCollectS {
  152. @autoreleasepool {
  153. [self testStruct];
  154. }
  155. TestpkgGC();
  156. long numS = TestpkgCollectS2(
  157. 1, 10); // within 10 seconds, collect the S used in testStruct.
  158. XCTAssertEqual(numS, 1, @"%ld S objects were collected; S used in testStruct is supposed to "
  159. @"be collected.",
  160. numS);
  161. }
  162. - (void)testBytesAppend {
  163. NSString *a = @"Foo";
  164. NSString *b = @"Bar";
  165. NSData *data_a = [a dataUsingEncoding:NSUTF8StringEncoding];
  166. NSData *data_b = [b dataUsingEncoding:NSUTF8StringEncoding];
  167. NSData *gotData = TestpkgBytesAppend(data_a, data_b);
  168. NSString *got = [[NSString alloc] initWithData:gotData encoding:NSUTF8StringEncoding];
  169. NSString *want = [a stringByAppendingString:b];
  170. XCTAssertEqualObjects(got, want, @"want %@\nTestpkgBytesAppend(%@, %@) = %@", want, a, b, got);
  171. }
  172. - (void)testInterface {
  173. // Test Go object implementing testpkg.I is handled correctly.
  174. id<TestpkgI2> goObj = TestpkgNewI();
  175. int64_t got = [goObj times:10];
  176. XCTAssertEqual(got, 100, @"TestpkgNewI().times(10) = %lld; want %d", got, 100);
  177. int32_t key = -1;
  178. TestpkgRegisterI(key, goObj);
  179. int64_t got2 = TestpkgMultiply(key, 10);
  180. XCTAssertEqual(got, got2, @"TestpkgMultiply(10 * 10) = %lld; want %lld", got2, got);
  181. TestpkgUnregisterI(key);
  182. // Test Objective-C objects implementing testpkg.I is handled correctly.
  183. @autoreleasepool {
  184. for (int32_t i = 0; i < 10; i++) {
  185. Number *num = [[Number alloc] init];
  186. num.value = i;
  187. TestpkgRegisterI(i, num);
  188. }
  189. TestpkgGC();
  190. }
  191. // Registered Objective-C objects are pinned on Go side which must
  192. // prevent deallocation from Objective-C.
  193. for (int32_t i = 0; i < 10; i++) {
  194. int64_t got = TestpkgMultiply(i, 2);
  195. XCTAssertEqual(got, i * 2,@"TestpkgMultiply(%d, 2) = %lld; want %d", i, got, i * 2);
  196. TestpkgUnregisterI(i);
  197. TestpkgGC();
  198. }
  199. // Unregistered all Objective-C objects.
  200. }
  201. - (void)testCollectI {
  202. @autoreleasepool {
  203. [self testInterface];
  204. }
  205. XCTAssertEqual(numI, 1, @"%d I objects were collected; I used in testInterface is supposed "
  206. @"to be collected.", numI);
  207. }
  208. - (void)testConst {
  209. XCTAssertEqualObjects(TestpkgAString, @"a string", @"TestpkgAString = %@, want 'a string'", TestpkgAString);
  210. XCTAssertEqual(TestpkgAnInt, 7, @"TestpkgAnInt = %lld, want 7", TestpkgAnInt);
  211. XCTAssertTrue(ABS(TestpkgAFloat - 0.12345) < 0.0001, @"TestpkgAFloat = %f, want 0.12345", TestpkgAFloat);
  212. XCTAssertTrue(TestpkgABool == YES, @"TestpkgABool = %@, want YES", TestpkgAFloat ? @"YES" : @"NO");
  213. XCTAssertEqual(TestpkgMinInt32, INT32_MIN, @"TestpkgMinInt32 = %d, want %d", TestpkgMinInt32, INT32_MIN);
  214. XCTAssertEqual(TestpkgMaxInt32, INT32_MAX, @"TestpkgMaxInt32 = %d, want %d", TestpkgMaxInt32, INT32_MAX);
  215. XCTAssertEqual(TestpkgMinInt64, INT64_MIN, @"TestpkgMinInt64 = %lld, want %lld", TestpkgMinInt64, INT64_MIN);
  216. XCTAssertEqual(TestpkgMaxInt64, INT64_MAX, @"TestpkgMaxInt64 = %lld, want %lld", TestpkgMaxInt64, INT64_MAX);
  217. XCTAssertTrue(ABS(TestpkgSmallestNonzeroFloat64 -
  218. 4.940656458412465441765687928682213723651e-324) < 1e-323, @"TestpkgSmallestNonzeroFloat64 = %f, want %f",
  219. TestpkgSmallestNonzeroFloat64,
  220. 4.940656458412465441765687928682213723651e-324);
  221. XCTAssertTrue(ABS(TestpkgMaxFloat64 -
  222. 1.797693134862315708145274237317043567981e+308) < 0.0001, @"TestpkgMaxFloat64 = %f, want %f", TestpkgMaxFloat64,
  223. 1.797693134862315708145274237317043567981e+308);
  224. XCTAssertTrue(ABS(TestpkgSmallestNonzeroFloat32 -
  225. 1.401298464324817070923729583289916131280e-45) < 1e-44, @"TestpkgSmallestNonzeroFloat32 = %f, want %f",
  226. TestpkgSmallestNonzeroFloat32,
  227. 1.401298464324817070923729583289916131280e-45);
  228. XCTAssertTrue(ABS(TestpkgMaxFloat32 - 3.40282346638528859811704183484516925440e+38) < 0.0001,
  229. @"TestpkgMaxFloat32 = %f, want %f", TestpkgMaxFloat32, 3.40282346638528859811704183484516925440e+38);
  230. XCTAssertTrue(ABS(TestpkgLog2E - 1 / 0.693147180559945309417232121458176568075500134360255254120680009) < 0.0001,
  231. @"TestpkgLog2E = %f, want %f", TestpkgLog2E, 1 / 0.693147180559945309417232121458176568075500134360255254120680009);
  232. }
  233. - (void)testIssue12307 {
  234. Number *num = [[Number alloc] init];
  235. num.value = 1024;
  236. NSError *error;
  237. XCTAssertFalse(TestpkgCallIError(num, YES, &error), @"TestpkgCallIError(Number, YES) succeeded; want error");
  238. NSError *error2;
  239. XCTAssertTrue(TestpkgCallIError(num, NO, &error2), @"TestpkgCallIError(Number, NO) failed(%@); want success", error2);
  240. }
  241. - (void)testErrorField {
  242. NSString *wantMsg = @"an error message";
  243. NSError *want = [NSError errorWithDomain:@"SeqTest" code:1 userInfo:@{NSLocalizedDescriptionKey: wantMsg}];
  244. TestpkgNode *n = TestpkgNewNode(@"ErrTest");
  245. n.err = want;
  246. NSError *got = n.err;
  247. XCTAssertEqual(got, want, @"got different objects after roundtrip");
  248. NSString *gotMsg = TestpkgErrorMessage(want);
  249. XCTAssertEqualObjects(gotMsg, wantMsg, @"err = %@, want %@", gotMsg, wantMsg);
  250. }
  251. - (void)testErrorDup {
  252. NSError *err = Testpkg.globalErr;
  253. XCTAssertTrue(TestpkgIsGlobalErr(err), @"A Go error must preserve its identity across the boundary");
  254. XCTAssertEqualObjects([err localizedDescription], @"global err", "A Go error message must be preserved");
  255. }
  256. - (void)testVar {
  257. NSString *s = Testpkg.stringVar;
  258. XCTAssertEqualObjects(s, @"a string var", @"Testpkg.StringVar = %@, want 'a string var'", s);
  259. s = @"a new string var";
  260. Testpkg.stringVar = s;
  261. NSString *s2 = Testpkg.stringVar;
  262. XCTAssertEqualObjects(s2, s, @"Testpkg.stringVar = %@, want %@", s2, s);
  263. int64_t i = Testpkg.intVar;
  264. XCTAssertEqual(i, 77, @"Testpkg.intVar = %lld, want 77", i);
  265. Testpkg.intVar = 777;
  266. i = Testpkg.intVar;
  267. XCTAssertEqual(i, 777, @"Testpkg.intVar = %lld, want 777", i);
  268. [Testpkg setIntVar:7777];
  269. i = [Testpkg intVar];
  270. XCTAssertEqual(i, 7777, @"Testpkg.intVar = %lld, want 7777", i);
  271. TestpkgNode *n0 = Testpkg.nodeVar;
  272. XCTAssertEqualObjects(n0.v, @"a struct var", @"Testpkg.NodeVar = %@, want 'a struct var'", n0.v);
  273. TestpkgNode *n1 = TestpkgNewNode(@"a new struct var");
  274. Testpkg.nodeVar = n1;
  275. TestpkgNode *n2 = Testpkg.nodeVar;
  276. XCTAssertEqualObjects(n2.v, @"a new struct var", @"Testpkg.NodeVar = %@, want 'a new struct var'", n2.v);
  277. Number *num = [[Number alloc] init];
  278. num.value = 12345;
  279. Testpkg.interfaceVar2 = num;
  280. id<TestpkgI2> iface = Testpkg.interfaceVar2;
  281. int64_t x = [iface times:10];
  282. int64_t y = [num times:10];
  283. XCTAssertEqual(x, y, @"Testpkg.InterfaceVar2 Times 10 = %lld, want %lld", x, y);
  284. }
  285. - (void)testIssue12403 {
  286. Number *num = [[Number alloc] init];
  287. num.value = 1024;
  288. NSError *error;
  289. NSString *ret = TestpkgCallIStringError(num, @"alphabet", &error);
  290. XCTAssertNil(ret, @"TestpkgCallIStringError(Number, 'alphabet') succeeded(%@); want error", ret);
  291. NSString *desc = [error localizedDescription];
  292. XCTAssertEqualObjects(desc, @"NumberError", @"TestpkgCallIStringError(Number, 'alphabet') returned unexpected error message %@", desc);
  293. NSError *error2;
  294. NSString *ret2 = TestpkgCallIStringError(num, @"number", &error2);
  295. XCTAssertNotNil(ret2, @"TestpkgCallIStringError(Number, 'number') failed(%@); want success", error2);
  296. XCTAssertEqualObjects(ret2, @"OK", @"TestpkgCallIStringError(Number, 'number') returned unexpected results %@", ret2);
  297. }
  298. - (void)testStrDup:(NSString *)want {
  299. NSString *got = TestpkgStrDup(want);
  300. XCTAssertEqualObjects(want, got, @"StrDup returned %@; expected %@", got, want);
  301. }
  302. - (void)testUnicodeStrings {
  303. [self testStrDup:@"abcxyz09{}"];
  304. [self testStrDup:@"Hello, 世界"];
  305. [self testStrDup:@"\uffff\U00010000\U00010001\U00012345\U0010ffff"];
  306. }
  307. - (void)testByteArrayRead {
  308. NSData *arr = [NSMutableData dataWithLength:8];
  309. long n;
  310. XCTAssertTrue(TestpkgReadIntoByteArray(arr, &n, nil), @"ReadIntoByteArray failed");
  311. XCTAssertEqual(n, 8, @"ReadIntoByteArray wrote %ld bytes, expected %d", n, 8);
  312. const uint8_t *b = [arr bytes];
  313. for (int i = 0; i < [arr length]; i++) {
  314. XCTAssertEqual(b[i], i, @"ReadIntoByteArray wrote %d at %d; expected %d", b[i], i, i);
  315. }
  316. // Test that immutable data cannot be changed from Go
  317. const uint8_t buf[] = {42};
  318. arr = [NSData dataWithBytes:buf length:1];
  319. XCTAssertTrue(TestpkgReadIntoByteArray(arr, &n, nil), @"ReadIntoByteArray failed");
  320. XCTAssertEqual(n, 1, @"ReadIntoByteArray wrote %ld bytes, expected %d", n, 8);
  321. b = [arr bytes];
  322. XCTAssertEqual(b[0], 42, @"ReadIntoByteArray wrote to an immutable NSData; expected no change");
  323. }
  324. - (void)testNilField {
  325. TestpkgNullFieldStruct *s = TestpkgNewNullFieldStruct();
  326. XCTAssertNil([s f], @"NullFieldStruct has non-nil field; expected nil");
  327. }
  328. - (void)testNullReferences {
  329. NullTest *t = [[NullTest alloc] init];
  330. XCTAssertTrue(TestpkgCallWithNull(nil, t), @"Testpkg.CallWithNull failed");
  331. id<TestpkgI> i = TestpkgNewNullInterface();
  332. XCTAssertNil(i, @"NewNullInterface() returned %p; expected nil", i);
  333. TestpkgS *s = TestpkgNewNullStruct();
  334. XCTAssertNil(s, @"NewNullStruct() returned %p; expected nil", s);
  335. TestpkgIssue20330 *nullArger = TestpkgNewIssue20330();
  336. XCTAssertTrue([nullArger callWithNull:nil], @"Issue20330.CallWithNull failed");
  337. }
  338. - (void)testReturnsError {
  339. NSError *error;
  340. NSString *value = TestpkgReturnsError(TRUE, &error);
  341. NSString *got = [error.userInfo valueForKey:NSLocalizedDescriptionKey];
  342. NSString *want = @"Error";
  343. XCTAssertEqualObjects(got, want, @"want %@\nTestpkgReturnsError(TRUE) = (%@, %@)", want, value, got);
  344. }
  345. - (void)testImportedPkg {
  346. XCTAssertEqualObjects(SecondpkgHelloString, SecondpkgHello(), @"imported string should match");
  347. id<SecondpkgI> i = TestpkgNewImportedI();
  348. SecondpkgS *s = TestpkgNewImportedS();
  349. XCTAssertEqual(8, [i f:8], @"numbers should match");
  350. XCTAssertEqual(8, [s f:8], @"numbers should match");
  351. i = TestpkgWithImportedI(i);
  352. s = TestpkgWithImportedS(s);
  353. i = [Testpkg importedVarI];
  354. s = [Testpkg importedVarS];
  355. [Testpkg setImportedVarI:i];
  356. [Testpkg setImportedVarS:s];
  357. TestpkgImportedFields *fields = TestpkgNewImportedFields();
  358. i = [fields i];
  359. s = [fields s];
  360. [fields setI:i];
  361. [fields setS:s];
  362. }
  363. - (void)testRoundTripEquality {
  364. Number *want = [[Number alloc] init];
  365. Number *got = (Number *)TestpkgI2Dup(want);
  366. XCTAssertEqual(got, want, @"ObjC object passed through Go should not be wrapped");
  367. IDup *idup = [[IDup alloc] init];
  368. XCTAssertTrue(TestpkgCallIDupper(idup), @"Go interface passed through ObjC should not be wrapped");
  369. CDup *cdup = [[CDup alloc] init];
  370. XCTAssertTrue(TestpkgCallCDupper(cdup), @"Go struct passed through ObjC should not be wrapped");
  371. }
  372. - (void)testEmptyError {
  373. NSError *error;
  374. XCTAssertFalse(TestpkgEmptyError(&error), @"GoTestpkgEmptyError succeeded; want error");
  375. XCTAssertNotNil(error, @"TestpkgEmptyError returned nil error");
  376. id<TestpkgEmptyErrorer> empty = [[EmptyErrorer alloc] init];
  377. XCTAssertFalse(TestpkgCallEmptyError(empty, &error), @"TestpkgCallEmptyError succeeded; want error");
  378. XCTAssertNotNil(error, @"TestpkgCallEmptyError returned nil error");
  379. }
  380. - (void)testSIGPIPE {
  381. TestpkgTestSIGPIPE();
  382. }
  383. - (void)testTags {
  384. XCTAssertEqual(42, TestpkgTaggedConst, @"Tagged const must exist");
  385. }
  386. - (void)testConstructors {
  387. id<TestpkgInterface> i = [[TestpkgConcrete alloc] init];
  388. [i f];
  389. TestpkgS2 *s = [[TestpkgS2 alloc] init:1 y:2];
  390. XCTAssertEqual(3.0, [s sum]);
  391. XCTAssertEqualObjects(@"gostring", [s tryTwoStrings:@"go" second:@"string"]);
  392. TestpkgS3 *s3 __attribute__((unused)) = [[TestpkgS3 alloc] init];
  393. TestpkgS4 *s4 = [[TestpkgS4 alloc] initWithInt:123];
  394. XCTAssertEqual(123, s4.i);
  395. s4 = [[TestpkgS4 alloc] initWithFloat: 123.456];
  396. XCTAssertEqual(123, s4.i);
  397. s4 = [[TestpkgS4 alloc] initWithBoolAndError: false];
  398. XCTAssertEqual(0, s4.i);
  399. s4 = [[TestpkgS4 alloc] initWithBoolAndError: true];
  400. XCTAssertEqual(s4, NULL);
  401. }
  402. @end