github.com/c-darwin/mobile@v0.0.0-20160313183840-ff625c46f7c9/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  // +build ignore
     6  
     7  #import <Foundation/Foundation.h>
     8  #import "GoTestpkg.h"
     9  
    10  #define ERROR(...)                                                             \
    11    do {                                                                         \
    12      NSLog(__VA_ARGS__);                                                        \
    13      err = 1;                                                                   \
    14    } while (0);
    15  
    16  static int err = 0;
    17  
    18  void testHello(NSString *input) {
    19    NSString *got = GoTestpkgHello(input);
    20    NSString *want = [NSString stringWithFormat:@"Hello, %@!", input];
    21    if (!got) {
    22      ERROR(@"GoTestpkgHello(%@)= NULL, want %@", input, want);
    23      return;
    24    }
    25    if (![got isEqualToString:want]) {
    26      ERROR(@"want %@\nGoTestpkgHello(%@)= %@", want, input, got);
    27    }
    28  }
    29  
    30  void testBytesAppend(NSString *a, NSString *b) {
    31    NSData *data_a = [a dataUsingEncoding:NSUTF8StringEncoding];
    32    NSData *data_b = [b dataUsingEncoding:NSUTF8StringEncoding];
    33    NSData *gotData = GoTestpkgBytesAppend(data_a, data_b);
    34    NSString *got =
    35        [[NSString alloc] initWithData:gotData encoding:NSUTF8StringEncoding];
    36    NSString *want = [a stringByAppendingString:b];
    37    if (![got isEqualToString:want]) {
    38      ERROR(@"want %@\nGoTestpkgBytesAppend(%@, %@) = %@", want, a, b, got);
    39    }
    40  }
    41  
    42  void testReturnsError() {
    43    NSString *value;
    44    NSError *error;
    45    GoTestpkgReturnsError(TRUE, &value, &error);
    46    NSString *got = [error.userInfo valueForKey:NSLocalizedDescriptionKey];
    47    NSString *want = @"Error";
    48    if (![got isEqualToString:want]) {
    49      ERROR(@"want %@\nGoTestpkgReturnsError(TRUE) = (%@, %@)", want, value, got);
    50    }
    51  }
    52  
    53  void testStruct() {
    54    GoTestpkgS *s = GoTestpkgNewS(10.0, 100.0);
    55    if (!s) {
    56      ERROR(@"GoTestpkgNewS returned NULL");
    57    }
    58  
    59    double x = [s X];
    60    double y = [s Y];
    61    double sum = [s Sum];
    62    if (x != 10.0 || y != 100.0 || sum != 110.0) {
    63      ERROR(@"GoTestpkgS(10.0, 100.0).X=%f Y=%f SUM=%f; want 10, 100, 110", x, y,
    64            sum);
    65    }
    66  
    67    double sum2 = GoTestpkgCallSSum(s);
    68    if (sum != sum2) {
    69      ERROR(@"GoTestpkgCallSSum(s)=%f; want %f as returned by s.Sum", sum2, sum);
    70    }
    71  
    72    [s setX:7];
    73    [s setY:70];
    74    x = [s X];
    75    y = [s Y];
    76    sum = [s Sum];
    77    if (x != 7 || y != 70 || sum != 77) {
    78      ERROR(@"GoTestpkgS(7, 70).X=%f Y=%f SUM=%f; want 7, 70, 77", x, y, sum);
    79    }
    80  
    81    NSString *first = @"trytwotested";
    82    NSString *second = @"test";
    83    NSString *got = [s TryTwoStrings:first second:second];
    84    NSString *want = [first stringByAppendingString:second];
    85    if (![got isEqualToString:want]) {
    86      ERROR(@"GoTestpkgS_TryTwoStrings(%@, %@)= %@; want %@", first, second, got,
    87            want);
    88    }
    89  
    90    GoTestpkgGC();
    91  }
    92  
    93  // Objective-C implementation of testpkg.I.
    94  @interface Number : NSObject <GoTestpkgI> {
    95  }
    96  @property int32_t value;
    97  
    98  - (BOOL)Error:(BOOL)e error:(NSError **)error;
    99  - (int64_t)Times:(int32_t)v;
   100  @end
   101  
   102  // numI is incremented when the first numI objective-C implementation is
   103  // deallocated.
   104  static int numI = 0;
   105  
   106  @implementation Number {
   107  }
   108  @synthesize value;
   109  
   110  - (BOOL)Error:(BOOL)triggerError error:(NSError **)error {
   111    if (!triggerError) {
   112      return YES;
   113    }
   114    if (error != NULL) {
   115      *error = [NSError errorWithDomain:@"SeqTest" code:1 userInfo:NULL];
   116    }
   117    return NO;
   118  }
   119  
   120  - (int64_t)Times:(int32_t)v {
   121    return v * value;
   122  }
   123  - (void)dealloc {
   124    if (self.value == 0) {
   125      numI++;
   126    }
   127  }
   128  @end
   129  
   130  void testInterface() {
   131    // Test Go object implementing testpkg.I is handled correctly.
   132    id<GoTestpkgI> goObj = GoTestpkgNewI();
   133    int64_t got = [goObj Times:10];
   134    if (got != 100) {
   135      ERROR(@"GoTestpkgNewI().Times(10) = %lld; want %d", got, 100);
   136    }
   137    int32_t key = -1;
   138    GoTestpkgRegisterI(key, goObj);
   139    int64_t got2 = GoTestpkgMultiply(key, 10);
   140    if (got != got2) {
   141      ERROR(@"GoTestpkgMultiply(10 * 10) = %lld; want %lld", got2, got);
   142    }
   143    GoTestpkgUnregisterI(key);
   144  
   145    // Test Objective-C objects implementing testpkg.I is handled correctly.
   146    @autoreleasepool {
   147      for (int32_t i = 0; i < 10; i++) {
   148        Number *num = [[Number alloc] init];
   149        num.value = i;
   150        GoTestpkgRegisterI(i, num);
   151      }
   152      GoTestpkgGC();
   153    }
   154  
   155    // Registered Objective-C objects are pinned on Go side which must
   156    // prevent deallocation from Objective-C.
   157    for (int32_t i = 0; i < 10; i++) {
   158      int64_t got = GoTestpkgMultiply(i, 2);
   159      if (got != i * 2) {
   160        ERROR(@"GoTestpkgMultiply(%d, 2) = %lld; want %d", i, got, i * 2);
   161        return;
   162      }
   163      GoTestpkgUnregisterI(i);
   164      GoTestpkgGC();
   165    }
   166    // Unregistered all Objective-C objects.
   167  }
   168  
   169  void testIssue12307() {
   170    Number *num = [[Number alloc] init];
   171    num.value = 1024;
   172    NSError *error;
   173    if (GoTestpkgCallIError(num, YES, &error) == YES) {
   174      ERROR(@"GoTestpkgCallIError(Number, YES) succeeded; want error");
   175    }
   176    NSError *error2;
   177    if (GoTestpkgCallIError(num, NO, &error2) == NO) {
   178      ERROR(@"GoTestpkgCallIError(Number, NO) failed(%@); want success", error2);
   179    }
   180  }
   181  
   182  // Invokes functions and object methods defined in Testpkg.h.
   183  //
   184  // TODO(hyangah): apply testing framework (e.g. XCTestCase)
   185  // and test through xcodebuild.
   186  int main(void) {
   187    @autoreleasepool {
   188      GoTestpkgHi();
   189  
   190      GoTestpkgInt(42);
   191  
   192      int64_t sum = GoTestpkgSum(31, 21);
   193      if (sum != 52) {
   194        ERROR(@"GoTestpkgSum(31, 21) = %lld, want 52\n", sum);
   195      }
   196  
   197      testHello(@"세계"); // korean, utf-8, world.
   198  
   199      unichar t[] = {
   200          0xD83D, 0xDCA9,
   201      }; // utf-16, pile of poo.
   202      testHello([NSString stringWithCharacters:t length:2]);
   203  
   204      testBytesAppend(@"Foo", @"Bar");
   205  
   206      testStruct();
   207      int numS = GoTestpkgCollectS(
   208          1, 10); // within 10 seconds, collect the S used in testStruct.
   209      if (numS != 1) {
   210        ERROR(@"%d S objects were collected; S used in testStruct is supposed to "
   211              @"be collected.",
   212              numS);
   213      }
   214  
   215      @autoreleasepool {
   216        testInterface();
   217      }
   218      if (numI != 1) {
   219        ERROR(@"%d I objects were collected; I used in testInterface is supposed "
   220              @"to be collected.",
   221              numI);
   222      }
   223  
   224      testIssue12307();
   225    }
   226  
   227    fprintf(stderr, "%s\n", err ? "FAIL" : "PASS");
   228    return err;
   229  }