1// Protocol Buffers - Google's data interchange format 2// Copyright 2015 Google Inc. All rights reserved. 3// https://developers.google.com/protocol-buffers/ 4// 5// Redistribution and use in source and binary forms, with or without 6// modification, are permitted provided that the following conditions are 7// met: 8// 9// * Redistributions of source code must retain the above copyright 10// notice, this list of conditions and the following disclaimer. 11// * Redistributions in binary form must reproduce the above 12// copyright notice, this list of conditions and the following disclaimer 13// in the documentation and/or other materials provided with the 14// distribution. 15// * Neither the name of Google Inc. nor the names of its 16// contributors may be used to endorse or promote products derived from 17// this software without specific prior written permission. 18// 19// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 20// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 21// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 22// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 23// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 24// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 25// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 26// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 27// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 28// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 29// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 30 31#import "GPBWellKnownTypes.h" 32 33#import <XCTest/XCTest.h> 34 35#import "GPBTestUtilities.h" 36#import "google/protobuf/AnyTest.pbobjc.h" 37 38// Nanosecond time accuracy 39static const NSTimeInterval kTimeAccuracy = 1e-9; 40 41@interface WellKnownTypesTest : XCTestCase 42@end 43 44@implementation WellKnownTypesTest 45 46- (void)testTimeStamp { 47 // Test negative and positive values. 48 NSTimeInterval values[] = { 49 -428027599.483999967, -1234567.0, -0.5, 0, 0.75, 54321.0, 2468086,483999967 50 }; 51 for (size_t i = 0; i < GPBARRAYSIZE(values); ++i) { 52 NSTimeInterval value = values[i]; 53 54 // Test Creation - date. 55 NSDate *date = [NSDate dateWithTimeIntervalSince1970:value]; 56 GPBTimestamp *timeStamp = [[GPBTimestamp alloc] initWithDate:date]; 57 58 XCTAssertGreaterThanOrEqual(timeStamp.nanos, 0, 59 @"Offset %f - Date: %@", (double)value, date); 60 XCTAssertLessThan(timeStamp.nanos, 1e9, 61 @"Offset %f - Date: %@", (double)value, date); 62 63 // Comparing timeIntervals instead of directly comparing dates because date 64 // equality requires the time intervals to be exactly the same, and the 65 // timeintervals go through a bit of floating point error as they are 66 // converted back and forth from the internal representation. 67 XCTAssertEqualWithAccuracy(value, timeStamp.date.timeIntervalSince1970, 68 kTimeAccuracy, 69 @"Offset %f - Date: %@", (double)value, date); 70 [timeStamp release]; 71 72 // Test Creation - timeIntervalSince1970. 73 timeStamp = [[GPBTimestamp alloc] initWithTimeIntervalSince1970:value]; 74 75 XCTAssertGreaterThanOrEqual(timeStamp.nanos, 0, 76 @"Offset %f - Date: %@", (double)value, date); 77 XCTAssertLessThan(timeStamp.nanos, 1e9, 78 @"Offset %f - Date: %@", (double)value, date); 79 80 XCTAssertEqualWithAccuracy(value, timeStamp.timeIntervalSince1970, 81 kTimeAccuracy, 82 @"Offset %f - Date: %@", (double)value, date); 83 [timeStamp release]; 84 85 // Test Mutation - date. 86 timeStamp = [[GPBTimestamp alloc] init]; 87 timeStamp.date = date; 88 89 XCTAssertGreaterThanOrEqual(timeStamp.nanos, 0, 90 @"Offset %f - Date: %@", (double)value, date); 91 XCTAssertLessThan(timeStamp.nanos, 1e9, 92 @"Offset %f - Date: %@", (double)value, date); 93 94 XCTAssertEqualWithAccuracy(value, timeStamp.date.timeIntervalSince1970, 95 kTimeAccuracy, 96 @"Offset %f - Date: %@", (double)value, date); 97 [timeStamp release]; 98 99 // Test Mutation - timeIntervalSince1970. 100 timeStamp = [[GPBTimestamp alloc] init]; 101 timeStamp.timeIntervalSince1970 = value; 102 103 XCTAssertGreaterThanOrEqual(timeStamp.nanos, 0, 104 @"Offset %f - Date: %@", (double)value, date); 105 XCTAssertLessThan(timeStamp.nanos, 1e9, 106 @"Offset %f - Date: %@", (double)value, date); 107 108 XCTAssertEqualWithAccuracy(value, timeStamp.date.timeIntervalSince1970, 109 kTimeAccuracy, 110 @"Offset %f - Date: %@", (double)value, date); 111 112 [timeStamp release]; 113 } 114} 115 116- (void)testDuration { 117 // Test negative and positive values. 118 NSTimeInterval values[] = { -1000.0001, -500.0, -0.5, 0, 0.75, 1000.0, 2000.0002 }; 119 for (size_t i = 0; i < GPBARRAYSIZE(values); ++i) { 120 NSTimeInterval value = values[i]; 121 122 // Test Creation. 123 GPBDuration *duration = 124 [[GPBDuration alloc] initWithTimeInterval:value]; 125 XCTAssertEqualWithAccuracy(value, duration.timeInterval, kTimeAccuracy, 126 @"For interval %f", (double)value); 127 if (value > 0) { 128 XCTAssertGreaterThanOrEqual(duration.seconds, 0, 129 @"For interval %f", (double)value); 130 XCTAssertGreaterThanOrEqual(duration.nanos, 0, 131 @"For interval %f", (double)value); 132 } else { 133 XCTAssertLessThanOrEqual(duration.seconds, 0, 134 @"For interval %f", (double)value); 135 XCTAssertLessThanOrEqual(duration.nanos, 0, 136 @"For interval %f", (double)value); 137 } 138 [duration release]; 139 140 // Test Mutation. 141 duration = [[GPBDuration alloc] init]; 142 duration.timeInterval = value; 143 XCTAssertEqualWithAccuracy(value, duration.timeInterval, kTimeAccuracy, 144 @"For interval %f", (double)value); 145 if (value > 0) { 146 XCTAssertGreaterThanOrEqual(duration.seconds, 0, 147 @"For interval %f", (double)value); 148 XCTAssertGreaterThanOrEqual(duration.nanos, 0, 149 @"For interval %f", (double)value); 150 } else { 151 XCTAssertLessThanOrEqual(duration.seconds, 0, 152 @"For interval %f", (double)value); 153 XCTAssertLessThanOrEqual(duration.nanos, 0, 154 @"For interval %f", (double)value); 155 } 156 [duration release]; 157 } 158} 159 160- (void)testAnyHelpers { 161 162 // Set and extract covers most of the code. 163 164 TestAny *subMessage = [TestAny message]; 165 subMessage.int32Value = 12345; 166 TestAny *message = [TestAny message]; 167 NSError *err = nil; 168 message.anyValue = [GPBAny anyWithMessage:subMessage error:&err]; 169 XCTAssertNil(err); 170 171 NSData *data = message.data; 172 XCTAssertNotNil(data); 173 174 TestAny *message2 = [TestAny parseFromData:data error:&err]; 175 XCTAssertNil(err); 176 XCTAssertNotNil(message2); 177 XCTAssertTrue(message2.hasAnyValue); 178 179 TestAny *subMessage2 = 180 (TestAny *)[message.anyValue unpackMessageClass:[TestAny class] 181 error:&err]; 182 XCTAssertNil(err); 183 XCTAssertNotNil(subMessage2); 184 XCTAssertEqual(subMessage2.int32Value, 12345); 185 186 // NULL errorPtr in the two calls. 187 188 message.anyValue = [GPBAny anyWithMessage:subMessage error:NULL]; 189 NSData *data2 = message.data; 190 XCTAssertEqualObjects(data2, data); 191 192 TestAny *subMessage3 = 193 (TestAny *)[message.anyValue unpackMessageClass:[TestAny class] 194 error:NULL]; 195 XCTAssertNotNil(subMessage3); 196 XCTAssertEqualObjects(subMessage2, subMessage3); 197 198 // Try to extract wrong type. 199 200 GPBTimestamp *wrongMessage = 201 (GPBTimestamp *)[message.anyValue unpackMessageClass:[GPBTimestamp class] 202 error:&err]; 203 XCTAssertNotNil(err); 204 XCTAssertNil(wrongMessage); 205 XCTAssertEqualObjects(err.domain, GPBWellKnownTypesErrorDomain); 206 XCTAssertEqual(err.code, GPBWellKnownTypesErrorCodeTypeURLMismatch); 207 208 wrongMessage = 209 (GPBTimestamp *)[message.anyValue unpackMessageClass:[GPBTimestamp class] 210 error:NULL]; 211 XCTAssertNil(wrongMessage); 212} 213 214@end 215