github.com/cyrilou242/gomobile-java@v0.0.0-20220215185836-09daef25a210/bind/objc/SeqTest.m (about)

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