1// Protocol Buffers - Google's data interchange format 2// Copyright 2015 Google Inc. All rights reserved. 3// 4// Use of this source code is governed by a BSD-style 5// license that can be found in the LICENSE file or at 6// https://developers.google.com/open-source/licenses/bsd 7 8#import <XCTest/XCTest.h> 9 10#import "GPBTestUtilities.h" 11#import "GPBWellKnownTypes.h" 12#import "objectivec/Tests/AnyTest.pbobjc.h" 13 14// Nanosecond time accuracy 15static const NSTimeInterval kTimeAccuracy = 1e-9; 16 17@interface WellKnownTypesTest : XCTestCase 18@end 19 20@implementation WellKnownTypesTest 21 22- (void)testTimeStamp { 23 // Test negative and positive values. 24 NSTimeInterval values[] = { 25 -428027599.483999967, -1234567.0, -0.5, 0, 0.75, 54321.0, 2468086, 483999967}; 26 for (size_t i = 0; i < GPBARRAYSIZE(values); ++i) { 27 NSTimeInterval value = values[i]; 28 29 // Test Creation - date. 30 NSDate *date = [NSDate dateWithTimeIntervalSince1970:value]; 31 GPBTimestamp *timeStamp = [[GPBTimestamp alloc] initWithDate:date]; 32 33 XCTAssertGreaterThanOrEqual(timeStamp.nanos, 0, @"Offset %f - Date: %@", (double)value, date); 34 XCTAssertLessThan(timeStamp.nanos, 1e9, @"Offset %f - Date: %@", (double)value, date); 35 36 // Comparing timeIntervals instead of directly comparing dates because date 37 // equality requires the time intervals to be exactly the same, and the 38 // timeintervals go through a bit of floating point error as they are 39 // converted back and forth from the internal representation. 40 XCTAssertEqualWithAccuracy(value, timeStamp.date.timeIntervalSince1970, kTimeAccuracy, 41 @"Offset %f - Date: %@", (double)value, date); 42 [timeStamp release]; 43 44 // Test Creation - timeIntervalSince1970. 45 timeStamp = [[GPBTimestamp alloc] initWithTimeIntervalSince1970:value]; 46 47 XCTAssertGreaterThanOrEqual(timeStamp.nanos, 0, @"Offset %f - Date: %@", (double)value, date); 48 XCTAssertLessThan(timeStamp.nanos, 1e9, @"Offset %f - Date: %@", (double)value, date); 49 50 XCTAssertEqualWithAccuracy(value, timeStamp.timeIntervalSince1970, kTimeAccuracy, 51 @"Offset %f - Date: %@", (double)value, date); 52 [timeStamp release]; 53 54 // Test Mutation - date. 55 timeStamp = [[GPBTimestamp alloc] init]; 56 timeStamp.date = date; 57 58 XCTAssertGreaterThanOrEqual(timeStamp.nanos, 0, @"Offset %f - Date: %@", (double)value, date); 59 XCTAssertLessThan(timeStamp.nanos, 1e9, @"Offset %f - Date: %@", (double)value, date); 60 61 XCTAssertEqualWithAccuracy(value, timeStamp.date.timeIntervalSince1970, kTimeAccuracy, 62 @"Offset %f - Date: %@", (double)value, date); 63 [timeStamp release]; 64 65 // Test Mutation - timeIntervalSince1970. 66 timeStamp = [[GPBTimestamp alloc] init]; 67 timeStamp.timeIntervalSince1970 = value; 68 69 XCTAssertGreaterThanOrEqual(timeStamp.nanos, 0, @"Offset %f - Date: %@", (double)value, date); 70 XCTAssertLessThan(timeStamp.nanos, 1e9, @"Offset %f - Date: %@", (double)value, date); 71 72 XCTAssertEqualWithAccuracy(value, timeStamp.date.timeIntervalSince1970, kTimeAccuracy, 73 @"Offset %f - Date: %@", (double)value, date); 74 75 [timeStamp release]; 76 } 77} 78 79- (void)testDuration { 80 // Test negative and positive values. 81 NSTimeInterval values[] = {-1000.0001, -500.0, -0.5, 0, 0.75, 1000.0, 2000.0002}; 82 for (size_t i = 0; i < GPBARRAYSIZE(values); ++i) { 83 NSTimeInterval value = values[i]; 84 85 // Test Creation. 86 GPBDuration *duration = [[GPBDuration alloc] initWithTimeInterval:value]; 87 XCTAssertEqualWithAccuracy(value, duration.timeInterval, kTimeAccuracy, @"For interval %f", 88 (double)value); 89 if (value > 0) { 90 XCTAssertGreaterThanOrEqual(duration.seconds, 0, @"For interval %f", (double)value); 91 XCTAssertGreaterThanOrEqual(duration.nanos, 0, @"For interval %f", (double)value); 92 } else { 93 XCTAssertLessThanOrEqual(duration.seconds, 0, @"For interval %f", (double)value); 94 XCTAssertLessThanOrEqual(duration.nanos, 0, @"For interval %f", (double)value); 95 } 96 [duration release]; 97 98 // Test Mutation. 99 duration = [[GPBDuration alloc] init]; 100 duration.timeInterval = value; 101 XCTAssertEqualWithAccuracy(value, duration.timeInterval, kTimeAccuracy, @"For interval %f", 102 (double)value); 103 if (value > 0) { 104 XCTAssertGreaterThanOrEqual(duration.seconds, 0, @"For interval %f", (double)value); 105 XCTAssertGreaterThanOrEqual(duration.nanos, 0, @"For interval %f", (double)value); 106 } else { 107 XCTAssertLessThanOrEqual(duration.seconds, 0, @"For interval %f", (double)value); 108 XCTAssertLessThanOrEqual(duration.nanos, 0, @"For interval %f", (double)value); 109 } 110 [duration release]; 111 } 112} 113 114- (void)testAnyHelpers { 115 // Set and extract covers most of the code. 116 117 AnyTestMessage *subMessage = [AnyTestMessage message]; 118 subMessage.int32Value = 12345; 119 AnyTestMessage *message = [AnyTestMessage message]; 120 NSError *err = nil; 121 message.anyValue = [GPBAny anyWithMessage:subMessage error:&err]; 122 XCTAssertNil(err); 123 124 NSData *data = message.data; 125 XCTAssertNotNil(data); 126 127 AnyTestMessage *message2 = [AnyTestMessage parseFromData:data error:&err]; 128 XCTAssertNil(err); 129 XCTAssertNotNil(message2); 130 XCTAssertTrue(message2.hasAnyValue); 131 132 AnyTestMessage *subMessage2 = 133 (AnyTestMessage *)[message.anyValue unpackMessageClass:[AnyTestMessage class] error:&err]; 134 XCTAssertNil(err); 135 XCTAssertNotNil(subMessage2); 136 XCTAssertEqual(subMessage2.int32Value, 12345); 137 138 // NULL errorPtr in the two calls. 139 140 message.anyValue = [GPBAny anyWithMessage:subMessage error:NULL]; 141 NSData *data2 = message.data; 142 XCTAssertEqualObjects(data2, data); 143 144 AnyTestMessage *subMessage3 = 145 (AnyTestMessage *)[message.anyValue unpackMessageClass:[AnyTestMessage class] error:NULL]; 146 XCTAssertNotNil(subMessage3); 147 XCTAssertEqualObjects(subMessage2, subMessage3); 148 149 // Try to extract wrong type. 150 151 GPBTimestamp *wrongMessage = 152 (GPBTimestamp *)[message.anyValue unpackMessageClass:[GPBTimestamp class] error:&err]; 153 XCTAssertNotNil(err); 154 XCTAssertNil(wrongMessage); 155 XCTAssertEqualObjects(err.domain, GPBWellKnownTypesErrorDomain); 156 XCTAssertEqual(err.code, GPBWellKnownTypesErrorCodeTypeURLMismatch); 157 158 wrongMessage = (GPBTimestamp *)[message.anyValue unpackMessageClass:[GPBTimestamp class] 159 error:NULL]; 160 XCTAssertNil(wrongMessage); 161} 162 163@end 164