diff --git a/objectivec/GPBDescriptor.m b/objectivec/GPBDescriptor.m index 0753a9485..3c3844da6 100644 --- a/objectivec/GPBDescriptor.m +++ b/objectivec/GPBDescriptor.m @@ -1027,10 +1027,6 @@ uint32_t GPBFieldAlternateTag(GPBFieldDescriptor *self) { return GPBExtensionIsRepeated(description_); } -- (BOOL)isMap { - return (description_->options & GPBFieldMapKeyMask) != 0; -} - - (BOOL)isPackable { return GPBExtensionIsPacked(description_); } diff --git a/objectivec/GPBUnknownField.m b/objectivec/GPBUnknownField.m index 15e0a6dce..9d5c97f38 100644 --- a/objectivec/GPBUnknownField.m +++ b/objectivec/GPBUnknownField.m @@ -97,6 +97,7 @@ if (self == object) return YES; if (![object isKindOfClass:[GPBUnknownField class]]) return NO; GPBUnknownField *field = (GPBUnknownField *)object; + if (number_ != field->number_) return NO; BOOL equalVarint = (mutableVarintList_.count == 0 && field->mutableVarintList_.count == 0) || [mutableVarintList_ isEqual:field->mutableVarintList_]; @@ -202,8 +203,9 @@ } - (NSString *)description { - NSMutableString *description = [NSMutableString - stringWithFormat:@"<%@ %p>: Field: %d {\n", [self class], self, number_]; + NSMutableString *description = + [NSMutableString stringWithFormat:@"<%@ %p>: Field: %d {\n", + [self class], self, number_]; [mutableVarintList_ enumerateValuesWithBlock:^(uint64_t value, NSUInteger idx, BOOL *stop) { #pragma unused(idx, stop) diff --git a/objectivec/Tests/GPBArrayTests.m b/objectivec/Tests/GPBArrayTests.m index 31f75501d..e414d90a6 100644 --- a/objectivec/Tests/GPBArrayTests.m +++ b/objectivec/Tests/GPBArrayTests.m @@ -39,6 +39,7 @@ // To let the testing macros work, add some extra methods to simplify things. @interface GPBEnumArray (TestingTweak) + (instancetype)arrayWithValue:(int32_t)value; ++ (instancetype)arrayWithCapacity:(NSUInteger)count; - (instancetype)initWithValues:(const int32_t [])values count:(NSUInteger)count; @end @@ -72,6 +73,10 @@ static BOOL TestingEnum_IsValidValue2(int32_t value) { rawValues:&value count:1] autorelease]; } ++ (instancetype)arrayWithCapacity:(NSUInteger)count { + return [[[self alloc] initWithValidationFunction:TestingEnum_IsValidValue + capacity:count] autorelease]; +} - (instancetype)initWithValues:(const int32_t [])values count:(NSUInteger)count { return [self initWithValidationFunction:TestingEnum_IsValidValue @@ -177,6 +182,8 @@ static BOOL TestingEnum_IsValidValue2(int32_t value) { //% XCTAssertNotEqual(idx, 0U); //% ++idx2; //% }]; +//% // Ensure description doesn't choke. +//% XCTAssertTrue(array.description.length > 10); //% [array release]; //%} //% @@ -201,6 +208,10 @@ static BOOL TestingEnum_IsValidValue2(int32_t value) { //% NAME$S count:GPBARRAYSIZE(kValues3)]; //% XCTAssertNotNil(array3); //% +//% // Identity +//% XCTAssertTrue([array1 isEqual:array1]); +//% // Wrong type doesn't blow up. +//% XCTAssertFalse([array1 isEqual:@"bogus"]); //% // 1/1Prime should be different objects, but equal. //% XCTAssertNotEqual(array1, array1prime); //% XCTAssertEqualObjects(array1, array1prime); @@ -271,6 +282,12 @@ static BOOL TestingEnum_IsValidValue2(int32_t value) { //% [array add##HELPER##ValuesFromArray:array2]; //% XCTAssertEqual(array.count, 5U); //% +//% // Zero/nil inputs do nothing. +//% [array addValues:kValues1 count:0]; +//% XCTAssertEqual(array.count, 5U); +//% [array addValues:NULL count:5]; +//% XCTAssertEqual(array.count, 5U); +//% //% XCTAssertEqual([array valueAtIndex:0], VAL1); //% XCTAssertEqual([array valueAtIndex:1], VAL2); //% XCTAssertEqual([array valueAtIndex:2], VAL3); @@ -391,9 +408,9 @@ static BOOL TestingEnum_IsValidValue2(int32_t value) { //%- (void)testInternalResizing { //% const TYPE kValues[] = { VAL1, VAL2, VAL3, VAL4 }; //% GPB##NAME##Array *array = -//% [[GPB##NAME##Array alloc] initWithValues:kValues -//% NAME$S count:GPBARRAYSIZE(kValues)]; +//% [GPB##NAME##Array arrayWithCapacity:GPBARRAYSIZE(kValues)]; //% XCTAssertNotNil(array); +//% [array addValues:kValues count:GPBARRAYSIZE(kValues)]; //% //% // Add/remove to trigger the intneral buffer to grow/shrink. //% for (int i = 0; i < 100; ++i) { @@ -410,7 +427,6 @@ static BOOL TestingEnum_IsValidValue2(int32_t value) { //% XCTAssertEqual(array.count, 404U); //% [array removeAll]; //% XCTAssertEqual(array.count, 0U); -//% [array release]; //%} //% //%@end @@ -510,6 +526,8 @@ static BOOL TestingEnum_IsValidValue2(int32_t value) { XCTAssertNotEqual(idx, 0U); ++idx2; }]; + // Ensure description doesn't choke. + XCTAssertTrue(array.description.length > 10); [array release]; } @@ -534,6 +552,10 @@ static BOOL TestingEnum_IsValidValue2(int32_t value) { count:GPBARRAYSIZE(kValues3)]; XCTAssertNotNil(array3); + // Identity + XCTAssertTrue([array1 isEqual:array1]); + // Wrong type doesn't blow up. + XCTAssertFalse([array1 isEqual:@"bogus"]); // 1/1Prime should be different objects, but equal. XCTAssertNotEqual(array1, array1prime); XCTAssertEqualObjects(array1, array1prime); @@ -604,6 +626,12 @@ static BOOL TestingEnum_IsValidValue2(int32_t value) { [array addValuesFromArray:array2]; XCTAssertEqual(array.count, 5U); + // Zero/nil inputs do nothing. + [array addValues:kValues1 count:0]; + XCTAssertEqual(array.count, 5U); + [array addValues:NULL count:5]; + XCTAssertEqual(array.count, 5U); + XCTAssertEqual([array valueAtIndex:0], 1); XCTAssertEqual([array valueAtIndex:1], 2); XCTAssertEqual([array valueAtIndex:2], 3); @@ -724,9 +752,9 @@ static BOOL TestingEnum_IsValidValue2(int32_t value) { - (void)testInternalResizing { const int32_t kValues[] = { 1, 2, 3, 4 }; GPBInt32Array *array = - [[GPBInt32Array alloc] initWithValues:kValues - count:GPBARRAYSIZE(kValues)]; + [GPBInt32Array arrayWithCapacity:GPBARRAYSIZE(kValues)]; XCTAssertNotNil(array); + [array addValues:kValues count:GPBARRAYSIZE(kValues)]; // Add/remove to trigger the intneral buffer to grow/shrink. for (int i = 0; i < 100; ++i) { @@ -743,7 +771,6 @@ static BOOL TestingEnum_IsValidValue2(int32_t value) { XCTAssertEqual(array.count, 404U); [array removeAll]; XCTAssertEqual(array.count, 0U); - [array release]; } @end @@ -843,6 +870,8 @@ static BOOL TestingEnum_IsValidValue2(int32_t value) { XCTAssertNotEqual(idx, 0U); ++idx2; }]; + // Ensure description doesn't choke. + XCTAssertTrue(array.description.length > 10); [array release]; } @@ -867,6 +896,10 @@ static BOOL TestingEnum_IsValidValue2(int32_t value) { count:GPBARRAYSIZE(kValues3)]; XCTAssertNotNil(array3); + // Identity + XCTAssertTrue([array1 isEqual:array1]); + // Wrong type doesn't blow up. + XCTAssertFalse([array1 isEqual:@"bogus"]); // 1/1Prime should be different objects, but equal. XCTAssertNotEqual(array1, array1prime); XCTAssertEqualObjects(array1, array1prime); @@ -937,6 +970,12 @@ static BOOL TestingEnum_IsValidValue2(int32_t value) { [array addValuesFromArray:array2]; XCTAssertEqual(array.count, 5U); + // Zero/nil inputs do nothing. + [array addValues:kValues1 count:0]; + XCTAssertEqual(array.count, 5U); + [array addValues:NULL count:5]; + XCTAssertEqual(array.count, 5U); + XCTAssertEqual([array valueAtIndex:0], 11U); XCTAssertEqual([array valueAtIndex:1], 12U); XCTAssertEqual([array valueAtIndex:2], 13U); @@ -1057,9 +1096,9 @@ static BOOL TestingEnum_IsValidValue2(int32_t value) { - (void)testInternalResizing { const uint32_t kValues[] = { 11U, 12U, 13U, 14U }; GPBUInt32Array *array = - [[GPBUInt32Array alloc] initWithValues:kValues - count:GPBARRAYSIZE(kValues)]; + [GPBUInt32Array arrayWithCapacity:GPBARRAYSIZE(kValues)]; XCTAssertNotNil(array); + [array addValues:kValues count:GPBARRAYSIZE(kValues)]; // Add/remove to trigger the intneral buffer to grow/shrink. for (int i = 0; i < 100; ++i) { @@ -1076,7 +1115,6 @@ static BOOL TestingEnum_IsValidValue2(int32_t value) { XCTAssertEqual(array.count, 404U); [array removeAll]; XCTAssertEqual(array.count, 0U); - [array release]; } @end @@ -1176,6 +1214,8 @@ static BOOL TestingEnum_IsValidValue2(int32_t value) { XCTAssertNotEqual(idx, 0U); ++idx2; }]; + // Ensure description doesn't choke. + XCTAssertTrue(array.description.length > 10); [array release]; } @@ -1200,6 +1240,10 @@ static BOOL TestingEnum_IsValidValue2(int32_t value) { count:GPBARRAYSIZE(kValues3)]; XCTAssertNotNil(array3); + // Identity + XCTAssertTrue([array1 isEqual:array1]); + // Wrong type doesn't blow up. + XCTAssertFalse([array1 isEqual:@"bogus"]); // 1/1Prime should be different objects, but equal. XCTAssertNotEqual(array1, array1prime); XCTAssertEqualObjects(array1, array1prime); @@ -1270,6 +1314,12 @@ static BOOL TestingEnum_IsValidValue2(int32_t value) { [array addValuesFromArray:array2]; XCTAssertEqual(array.count, 5U); + // Zero/nil inputs do nothing. + [array addValues:kValues1 count:0]; + XCTAssertEqual(array.count, 5U); + [array addValues:NULL count:5]; + XCTAssertEqual(array.count, 5U); + XCTAssertEqual([array valueAtIndex:0], 31LL); XCTAssertEqual([array valueAtIndex:1], 32LL); XCTAssertEqual([array valueAtIndex:2], 33LL); @@ -1390,9 +1440,9 @@ static BOOL TestingEnum_IsValidValue2(int32_t value) { - (void)testInternalResizing { const int64_t kValues[] = { 31LL, 32LL, 33LL, 34LL }; GPBInt64Array *array = - [[GPBInt64Array alloc] initWithValues:kValues - count:GPBARRAYSIZE(kValues)]; + [GPBInt64Array arrayWithCapacity:GPBARRAYSIZE(kValues)]; XCTAssertNotNil(array); + [array addValues:kValues count:GPBARRAYSIZE(kValues)]; // Add/remove to trigger the intneral buffer to grow/shrink. for (int i = 0; i < 100; ++i) { @@ -1409,7 +1459,6 @@ static BOOL TestingEnum_IsValidValue2(int32_t value) { XCTAssertEqual(array.count, 404U); [array removeAll]; XCTAssertEqual(array.count, 0U); - [array release]; } @end @@ -1509,6 +1558,8 @@ static BOOL TestingEnum_IsValidValue2(int32_t value) { XCTAssertNotEqual(idx, 0U); ++idx2; }]; + // Ensure description doesn't choke. + XCTAssertTrue(array.description.length > 10); [array release]; } @@ -1533,6 +1584,10 @@ static BOOL TestingEnum_IsValidValue2(int32_t value) { count:GPBARRAYSIZE(kValues3)]; XCTAssertNotNil(array3); + // Identity + XCTAssertTrue([array1 isEqual:array1]); + // Wrong type doesn't blow up. + XCTAssertFalse([array1 isEqual:@"bogus"]); // 1/1Prime should be different objects, but equal. XCTAssertNotEqual(array1, array1prime); XCTAssertEqualObjects(array1, array1prime); @@ -1603,6 +1658,12 @@ static BOOL TestingEnum_IsValidValue2(int32_t value) { [array addValuesFromArray:array2]; XCTAssertEqual(array.count, 5U); + // Zero/nil inputs do nothing. + [array addValues:kValues1 count:0]; + XCTAssertEqual(array.count, 5U); + [array addValues:NULL count:5]; + XCTAssertEqual(array.count, 5U); + XCTAssertEqual([array valueAtIndex:0], 41ULL); XCTAssertEqual([array valueAtIndex:1], 42ULL); XCTAssertEqual([array valueAtIndex:2], 43ULL); @@ -1723,9 +1784,9 @@ static BOOL TestingEnum_IsValidValue2(int32_t value) { - (void)testInternalResizing { const uint64_t kValues[] = { 41ULL, 42ULL, 43ULL, 44ULL }; GPBUInt64Array *array = - [[GPBUInt64Array alloc] initWithValues:kValues - count:GPBARRAYSIZE(kValues)]; + [GPBUInt64Array arrayWithCapacity:GPBARRAYSIZE(kValues)]; XCTAssertNotNil(array); + [array addValues:kValues count:GPBARRAYSIZE(kValues)]; // Add/remove to trigger the intneral buffer to grow/shrink. for (int i = 0; i < 100; ++i) { @@ -1742,7 +1803,6 @@ static BOOL TestingEnum_IsValidValue2(int32_t value) { XCTAssertEqual(array.count, 404U); [array removeAll]; XCTAssertEqual(array.count, 0U); - [array release]; } @end @@ -1842,6 +1902,8 @@ static BOOL TestingEnum_IsValidValue2(int32_t value) { XCTAssertNotEqual(idx, 0U); ++idx2; }]; + // Ensure description doesn't choke. + XCTAssertTrue(array.description.length > 10); [array release]; } @@ -1866,6 +1928,10 @@ static BOOL TestingEnum_IsValidValue2(int32_t value) { count:GPBARRAYSIZE(kValues3)]; XCTAssertNotNil(array3); + // Identity + XCTAssertTrue([array1 isEqual:array1]); + // Wrong type doesn't blow up. + XCTAssertFalse([array1 isEqual:@"bogus"]); // 1/1Prime should be different objects, but equal. XCTAssertNotEqual(array1, array1prime); XCTAssertEqualObjects(array1, array1prime); @@ -1936,6 +2002,12 @@ static BOOL TestingEnum_IsValidValue2(int32_t value) { [array addValuesFromArray:array2]; XCTAssertEqual(array.count, 5U); + // Zero/nil inputs do nothing. + [array addValues:kValues1 count:0]; + XCTAssertEqual(array.count, 5U); + [array addValues:NULL count:5]; + XCTAssertEqual(array.count, 5U); + XCTAssertEqual([array valueAtIndex:0], 51.f); XCTAssertEqual([array valueAtIndex:1], 52.f); XCTAssertEqual([array valueAtIndex:2], 53.f); @@ -2056,9 +2128,9 @@ static BOOL TestingEnum_IsValidValue2(int32_t value) { - (void)testInternalResizing { const float kValues[] = { 51.f, 52.f, 53.f, 54.f }; GPBFloatArray *array = - [[GPBFloatArray alloc] initWithValues:kValues - count:GPBARRAYSIZE(kValues)]; + [GPBFloatArray arrayWithCapacity:GPBARRAYSIZE(kValues)]; XCTAssertNotNil(array); + [array addValues:kValues count:GPBARRAYSIZE(kValues)]; // Add/remove to trigger the intneral buffer to grow/shrink. for (int i = 0; i < 100; ++i) { @@ -2075,7 +2147,6 @@ static BOOL TestingEnum_IsValidValue2(int32_t value) { XCTAssertEqual(array.count, 404U); [array removeAll]; XCTAssertEqual(array.count, 0U); - [array release]; } @end @@ -2175,6 +2246,8 @@ static BOOL TestingEnum_IsValidValue2(int32_t value) { XCTAssertNotEqual(idx, 0U); ++idx2; }]; + // Ensure description doesn't choke. + XCTAssertTrue(array.description.length > 10); [array release]; } @@ -2199,6 +2272,10 @@ static BOOL TestingEnum_IsValidValue2(int32_t value) { count:GPBARRAYSIZE(kValues3)]; XCTAssertNotNil(array3); + // Identity + XCTAssertTrue([array1 isEqual:array1]); + // Wrong type doesn't blow up. + XCTAssertFalse([array1 isEqual:@"bogus"]); // 1/1Prime should be different objects, but equal. XCTAssertNotEqual(array1, array1prime); XCTAssertEqualObjects(array1, array1prime); @@ -2269,6 +2346,12 @@ static BOOL TestingEnum_IsValidValue2(int32_t value) { [array addValuesFromArray:array2]; XCTAssertEqual(array.count, 5U); + // Zero/nil inputs do nothing. + [array addValues:kValues1 count:0]; + XCTAssertEqual(array.count, 5U); + [array addValues:NULL count:5]; + XCTAssertEqual(array.count, 5U); + XCTAssertEqual([array valueAtIndex:0], 61.); XCTAssertEqual([array valueAtIndex:1], 62.); XCTAssertEqual([array valueAtIndex:2], 63.); @@ -2389,9 +2472,9 @@ static BOOL TestingEnum_IsValidValue2(int32_t value) { - (void)testInternalResizing { const double kValues[] = { 61., 62., 63., 64. }; GPBDoubleArray *array = - [[GPBDoubleArray alloc] initWithValues:kValues - count:GPBARRAYSIZE(kValues)]; + [GPBDoubleArray arrayWithCapacity:GPBARRAYSIZE(kValues)]; XCTAssertNotNil(array); + [array addValues:kValues count:GPBARRAYSIZE(kValues)]; // Add/remove to trigger the intneral buffer to grow/shrink. for (int i = 0; i < 100; ++i) { @@ -2408,7 +2491,6 @@ static BOOL TestingEnum_IsValidValue2(int32_t value) { XCTAssertEqual(array.count, 404U); [array removeAll]; XCTAssertEqual(array.count, 0U); - [array release]; } @end @@ -2508,6 +2590,8 @@ static BOOL TestingEnum_IsValidValue2(int32_t value) { XCTAssertNotEqual(idx, 0U); ++idx2; }]; + // Ensure description doesn't choke. + XCTAssertTrue(array.description.length > 10); [array release]; } @@ -2532,6 +2616,10 @@ static BOOL TestingEnum_IsValidValue2(int32_t value) { count:GPBARRAYSIZE(kValues3)]; XCTAssertNotNil(array3); + // Identity + XCTAssertTrue([array1 isEqual:array1]); + // Wrong type doesn't blow up. + XCTAssertFalse([array1 isEqual:@"bogus"]); // 1/1Prime should be different objects, but equal. XCTAssertNotEqual(array1, array1prime); XCTAssertEqualObjects(array1, array1prime); @@ -2602,6 +2690,12 @@ static BOOL TestingEnum_IsValidValue2(int32_t value) { [array addValuesFromArray:array2]; XCTAssertEqual(array.count, 5U); + // Zero/nil inputs do nothing. + [array addValues:kValues1 count:0]; + XCTAssertEqual(array.count, 5U); + [array addValues:NULL count:5]; + XCTAssertEqual(array.count, 5U); + XCTAssertEqual([array valueAtIndex:0], TRUE); XCTAssertEqual([array valueAtIndex:1], TRUE); XCTAssertEqual([array valueAtIndex:2], FALSE); @@ -2722,9 +2816,9 @@ static BOOL TestingEnum_IsValidValue2(int32_t value) { - (void)testInternalResizing { const BOOL kValues[] = { TRUE, TRUE, FALSE, FALSE }; GPBBoolArray *array = - [[GPBBoolArray alloc] initWithValues:kValues - count:GPBARRAYSIZE(kValues)]; + [GPBBoolArray arrayWithCapacity:GPBARRAYSIZE(kValues)]; XCTAssertNotNil(array); + [array addValues:kValues count:GPBARRAYSIZE(kValues)]; // Add/remove to trigger the intneral buffer to grow/shrink. for (int i = 0; i < 100; ++i) { @@ -2741,7 +2835,6 @@ static BOOL TestingEnum_IsValidValue2(int32_t value) { XCTAssertEqual(array.count, 404U); [array removeAll]; XCTAssertEqual(array.count, 0U); - [array release]; } @end @@ -2841,6 +2934,8 @@ static BOOL TestingEnum_IsValidValue2(int32_t value) { XCTAssertNotEqual(idx, 0U); ++idx2; }]; + // Ensure description doesn't choke. + XCTAssertTrue(array.description.length > 10); [array release]; } @@ -2865,6 +2960,10 @@ static BOOL TestingEnum_IsValidValue2(int32_t value) { count:GPBARRAYSIZE(kValues3)]; XCTAssertNotNil(array3); + // Identity + XCTAssertTrue([array1 isEqual:array1]); + // Wrong type doesn't blow up. + XCTAssertFalse([array1 isEqual:@"bogus"]); // 1/1Prime should be different objects, but equal. XCTAssertNotEqual(array1, array1prime); XCTAssertEqualObjects(array1, array1prime); @@ -2935,6 +3034,12 @@ static BOOL TestingEnum_IsValidValue2(int32_t value) { [array addRawValuesFromArray:array2]; XCTAssertEqual(array.count, 5U); + // Zero/nil inputs do nothing. + [array addValues:kValues1 count:0]; + XCTAssertEqual(array.count, 5U); + [array addValues:NULL count:5]; + XCTAssertEqual(array.count, 5U); + XCTAssertEqual([array valueAtIndex:0], 71); XCTAssertEqual([array valueAtIndex:1], 72); XCTAssertEqual([array valueAtIndex:2], 73); @@ -3055,9 +3160,9 @@ static BOOL TestingEnum_IsValidValue2(int32_t value) { - (void)testInternalResizing { const int32_t kValues[] = { 71, 72, 73, 74 }; GPBEnumArray *array = - [[GPBEnumArray alloc] initWithValues:kValues - count:GPBARRAYSIZE(kValues)]; + [GPBEnumArray arrayWithCapacity:GPBARRAYSIZE(kValues)]; XCTAssertNotNil(array); + [array addValues:kValues count:GPBARRAYSIZE(kValues)]; // Add/remove to trigger the intneral buffer to grow/shrink. for (int i = 0; i < 100; ++i) { @@ -3074,7 +3179,6 @@ static BOOL TestingEnum_IsValidValue2(int32_t value) { XCTAssertEqual(array.count, 404U); [array removeAll]; XCTAssertEqual(array.count, 0U); - [array release]; } @end diff --git a/objectivec/Tests/GPBDescriptorTests.m b/objectivec/Tests/GPBDescriptorTests.m index 1e1c3de8d..199ea6557 100644 --- a/objectivec/Tests/GPBDescriptorTests.m +++ b/objectivec/Tests/GPBDescriptorTests.m @@ -32,7 +32,7 @@ #import -#import "GPBDescriptor.h" +#import "GPBDescriptor_PackagePrivate.h" #import "google/protobuf/Unittest.pbobjc.h" #import "google/protobuf/UnittestObjc.pbobjc.h" #import "google/protobuf/Descriptor.pbobjc.h" @@ -83,6 +83,8 @@ XCTAssertNotNil(fieldDescriptorWithNumber.enumDescriptor); XCTAssertEqualObjects(fieldDescriptorWithNumber.enumDescriptor.name, @"TestAllTypes_NestedEnum"); + XCTAssertEqual(fieldDescriptorWithName.number, fieldDescriptorWithNumber.number); + XCTAssertEqual(fieldDescriptorWithName.dataType, GPBDataTypeEnum); // Foreign Enum fieldDescriptorWithName = [descriptor fieldWithName:@"optionalForeignEnum"]; @@ -93,6 +95,8 @@ XCTAssertNotNil(fieldDescriptorWithNumber.enumDescriptor); XCTAssertEqualObjects(fieldDescriptorWithNumber.enumDescriptor.name, @"ForeignEnum"); + XCTAssertEqual(fieldDescriptorWithName.number, fieldDescriptorWithNumber.number); + XCTAssertEqual(fieldDescriptorWithName.dataType, GPBDataTypeEnum); // Import Enum fieldDescriptorWithName = [descriptor fieldWithName:@"optionalImportEnum"]; @@ -103,6 +107,8 @@ XCTAssertNotNil(fieldDescriptorWithNumber.enumDescriptor); XCTAssertEqualObjects(fieldDescriptorWithNumber.enumDescriptor.name, @"ImportEnum"); + XCTAssertEqual(fieldDescriptorWithName.number, fieldDescriptorWithNumber.number); + XCTAssertEqual(fieldDescriptorWithName.dataType, GPBDataTypeEnum); // Nested Message fieldDescriptorWithName = [descriptor fieldWithName:@"optionalNestedMessage"]; @@ -111,6 +117,8 @@ XCTAssertNotNil(fieldDescriptorWithNumber); XCTAssertEqual(fieldDescriptorWithName, fieldDescriptorWithNumber); XCTAssertNil(fieldDescriptorWithNumber.enumDescriptor); + XCTAssertEqual(fieldDescriptorWithName.number, fieldDescriptorWithNumber.number); + XCTAssertEqual(fieldDescriptorWithName.dataType, GPBDataTypeMessage); // Foreign Message fieldDescriptorWithName = @@ -120,6 +128,8 @@ XCTAssertNotNil(fieldDescriptorWithNumber); XCTAssertEqual(fieldDescriptorWithName, fieldDescriptorWithNumber); XCTAssertNil(fieldDescriptorWithNumber.enumDescriptor); + XCTAssertEqual(fieldDescriptorWithName.number, fieldDescriptorWithNumber.number); + XCTAssertEqual(fieldDescriptorWithName.dataType, GPBDataTypeMessage); // Import Message fieldDescriptorWithName = [descriptor fieldWithName:@"optionalImportMessage"]; @@ -128,6 +138,12 @@ XCTAssertNotNil(fieldDescriptorWithNumber); XCTAssertEqual(fieldDescriptorWithName, fieldDescriptorWithNumber); XCTAssertNil(fieldDescriptorWithNumber.enumDescriptor); + XCTAssertEqual(fieldDescriptorWithName.number, fieldDescriptorWithNumber.number); + XCTAssertEqual(fieldDescriptorWithName.dataType, GPBDataTypeMessage); + + // Some failed lookups. + XCTAssertNil([descriptor fieldWithName:@"NOT THERE"]); + XCTAssertNil([descriptor fieldWithNumber:9876543]); } - (void)testEnumDescriptor { @@ -159,6 +175,7 @@ XCTAssertNotNil(enumName); XCTAssertTrue([descriptor getValue:&value forEnumTextFormatName:@"FOO"]); XCTAssertEqual(value, TestAllTypes_NestedEnum_Foo); + XCTAssertNil([descriptor textFormatNameForValue:99999]); // Bad values enumName = [descriptor enumNameForValue:0]; @@ -253,4 +270,102 @@ XCTAssertNil(bazString.containingOneof); } +- (void)testExtensiondDescriptor { + Class msgClass = [TestAllExtensions class]; + Class packedMsgClass = [TestPackedExtensions class]; + + // Int + + GPBExtensionDescriptor *descriptor = [UnittestRoot optionalInt32Extension]; + XCTAssertNotNil(descriptor); + XCTAssertEqual(descriptor.containingMessageClass, msgClass); // ptr equality + XCTAssertFalse(descriptor.isPackable); + XCTAssertEqualObjects(descriptor.defaultValue, @0); + XCTAssertNil(descriptor.enumDescriptor); + + descriptor = [UnittestRoot defaultInt32Extension]; + XCTAssertNotNil(descriptor); + XCTAssertEqual(descriptor.containingMessageClass, msgClass); // ptr equality + XCTAssertFalse(descriptor.isPackable); + XCTAssertEqualObjects(descriptor.defaultValue, @41); + XCTAssertNil(descriptor.enumDescriptor); + + // Enum + + descriptor = [UnittestRoot optionalNestedEnumExtension]; + XCTAssertNotNil(descriptor); + XCTAssertEqual(descriptor.containingMessageClass, msgClass); // ptr equality + XCTAssertFalse(descriptor.isPackable); + XCTAssertEqual(descriptor.defaultValue, @1); + XCTAssertEqualObjects(descriptor.enumDescriptor.name, @"TestAllTypes_NestedEnum"); + + descriptor = [UnittestRoot defaultNestedEnumExtension]; + XCTAssertNotNil(descriptor); + XCTAssertEqual(descriptor.containingMessageClass, msgClass); // ptr equality + XCTAssertFalse(descriptor.isPackable); + XCTAssertEqual(descriptor.defaultValue, @2); + XCTAssertEqualObjects(descriptor.enumDescriptor.name, @"TestAllTypes_NestedEnum"); + + // Message + + descriptor = [UnittestRoot optionalNestedMessageExtension]; + XCTAssertNotNil(descriptor); + XCTAssertEqual(descriptor.containingMessageClass, msgClass); // ptr equality + XCTAssertFalse(descriptor.isPackable); + XCTAssertNil(descriptor.defaultValue); + XCTAssertNil(descriptor.enumDescriptor); + + // Repeated Int + + descriptor = [UnittestRoot repeatedInt32Extension]; + XCTAssertNotNil(descriptor); + XCTAssertEqual(descriptor.containingMessageClass, msgClass); // ptr equality + XCTAssertFalse(descriptor.isPackable); + XCTAssertNil(descriptor.defaultValue); + XCTAssertNil(descriptor.enumDescriptor); + + descriptor = [UnittestRoot packedInt32Extension]; + XCTAssertNotNil(descriptor); + XCTAssertEqual(descriptor.containingMessageClass, packedMsgClass); // ptr equality + XCTAssertTrue(descriptor.isPackable); + XCTAssertNil(descriptor.defaultValue); + XCTAssertNil(descriptor.enumDescriptor); + + // Repeated Enum + + descriptor = [UnittestRoot repeatedNestedEnumExtension]; + XCTAssertNotNil(descriptor); + XCTAssertEqual(descriptor.containingMessageClass, msgClass); // ptr equality + XCTAssertFalse(descriptor.isPackable); + XCTAssertNil(descriptor.defaultValue); + XCTAssertEqualObjects(descriptor.enumDescriptor.name, @"TestAllTypes_NestedEnum"); + + descriptor = [UnittestRoot packedEnumExtension]; + XCTAssertNotNil(descriptor); + XCTAssertEqual(descriptor.containingMessageClass, packedMsgClass); // ptr equality + XCTAssertTrue(descriptor.isPackable); + XCTAssertNil(descriptor.defaultValue); + XCTAssertEqualObjects(descriptor.enumDescriptor.name, @"ForeignEnum"); + + // Repeated Message + + descriptor = [UnittestRoot repeatedNestedMessageExtension]; + XCTAssertNotNil(descriptor); + XCTAssertEqual(descriptor.containingMessageClass, msgClass); // ptr equality + XCTAssertFalse(descriptor.isPackable); + XCTAssertNil(descriptor.defaultValue); + XCTAssertNil(descriptor.enumDescriptor); + + // Compare (used internally for serialization). + + GPBExtensionDescriptor *ext1 = [UnittestRoot optionalInt32Extension]; + XCTAssertEqual(ext1.fieldNumber, 1u); + GPBExtensionDescriptor *ext2 = [UnittestRoot optionalInt64Extension]; + XCTAssertEqual(ext2.fieldNumber, 2u); + + XCTAssertEqual([ext1 compareByFieldNumber:ext2], NSOrderedAscending); + XCTAssertEqual([ext2 compareByFieldNumber:ext1], NSOrderedDescending); + XCTAssertEqual([ext1 compareByFieldNumber:ext1], NSOrderedSame); +} + @end diff --git a/objectivec/Tests/GPBUnknownFieldSetTest.m b/objectivec/Tests/GPBUnknownFieldSetTest.m index 5a07ecc00..64cbd2d27 100644 --- a/objectivec/Tests/GPBUnknownFieldSetTest.m +++ b/objectivec/Tests/GPBUnknownFieldSetTest.m @@ -64,6 +64,95 @@ static NSData *DataFromCStr(const char *str) { unknownFields_ = emptyMessage_.unknownFields; } +- (void)testInvalidFieldNumber { + GPBUnknownFieldSet *set = [[[GPBUnknownFieldSet alloc] init] autorelease]; + GPBUnknownField* field = [[[GPBUnknownField alloc] initWithNumber:0] autorelease]; + XCTAssertThrowsSpecificNamed([set addField:field], NSException, NSInvalidArgumentException); +} + +- (void)testEqualityAndHash { + // Empty + + GPBUnknownFieldSet *set1 = [[[GPBUnknownFieldSet alloc] init] autorelease]; + XCTAssertTrue([set1 isEqual:set1]); + XCTAssertFalse([set1 isEqual:@"foo"]); + GPBUnknownFieldSet *set2 = [[[GPBUnknownFieldSet alloc] init] autorelease]; + XCTAssertEqualObjects(set1, set2); + XCTAssertEqual([set1 hash], [set2 hash]); + + // Varint + + GPBUnknownField* field1 = [[[GPBUnknownField alloc] initWithNumber:1] autorelease]; + [field1 addVarint:1]; + [set1 addField:field1]; + XCTAssertNotEqualObjects(set1, set2); + GPBUnknownField* field2 = [[[GPBUnknownField alloc] initWithNumber:1] autorelease]; + [field2 addVarint:1]; + [set2 addField:field2]; + XCTAssertEqualObjects(set1, set2); + XCTAssertEqual([set1 hash], [set2 hash]); + + // Fixed32 + + field1 = [[[GPBUnknownField alloc] initWithNumber:2] autorelease]; + [field1 addFixed32:2]; + [set1 addField:field1]; + XCTAssertNotEqualObjects(set1, set2); + field2 = [[[GPBUnknownField alloc] initWithNumber:2] autorelease]; + [field2 addFixed32:2]; + [set2 addField:field2]; + XCTAssertEqualObjects(set1, set2); + XCTAssertEqual([set1 hash], [set2 hash]); + + // Fixed64 + + field1 = [[[GPBUnknownField alloc] initWithNumber:3] autorelease]; + [field1 addFixed64:3]; + [set1 addField:field1]; + XCTAssertNotEqualObjects(set1, set2); + field2 = [[[GPBUnknownField alloc] initWithNumber:3] autorelease]; + [field2 addFixed64:3]; + [set2 addField:field2]; + XCTAssertEqualObjects(set1, set2); + XCTAssertEqual([set1 hash], [set2 hash]); + + // LengthDelimited + + field1 = [[[GPBUnknownField alloc] initWithNumber:4] autorelease]; + [field1 addLengthDelimited:DataFromCStr("foo")]; + [set1 addField:field1]; + XCTAssertNotEqualObjects(set1, set2); + field2 = [[[GPBUnknownField alloc] initWithNumber:4] autorelease]; + [field2 addLengthDelimited:DataFromCStr("foo")]; + [set2 addField:field2]; + XCTAssertEqualObjects(set1, set2); + XCTAssertEqual([set1 hash], [set2 hash]); + + // Group + + GPBUnknownFieldSet *group1 = [[[GPBUnknownFieldSet alloc] init] autorelease]; + GPBUnknownField* fieldGroup1 = [[[GPBUnknownField alloc] initWithNumber:10] autorelease]; + [fieldGroup1 addVarint:1]; + [group1 addField:fieldGroup1]; + GPBUnknownFieldSet *group2 = [[[GPBUnknownFieldSet alloc] init] autorelease]; + GPBUnknownField* fieldGroup2 = [[[GPBUnknownField alloc] initWithNumber:10] autorelease]; + [fieldGroup2 addVarint:1]; + [group2 addField:fieldGroup2]; + + field1 = [[[GPBUnknownField alloc] initWithNumber:5] autorelease]; + [field1 addGroup:group1]; + [set1 addField:field1]; + XCTAssertNotEqualObjects(set1, set2); + field2 = [[[GPBUnknownField alloc] initWithNumber:5] autorelease]; + [field2 addGroup:group2]; + [set2 addField:field2]; + XCTAssertEqualObjects(set1, set2); + XCTAssertEqual([set1 hash], [set2 hash]); + + // Exercise description for completeness. + XCTAssertTrue(set1.description.length > 10); +} + // Constructs a protocol buffer which contains fields with all the same // numbers as allFieldsData except that each field is some other wire // type. @@ -116,10 +205,25 @@ static NSData *DataFromCStr(const char *str) { field = [[[GPBUnknownField alloc] initWithNumber:3] autorelease]; [field addVarint:4]; [set1 addField:field]; + field = [[[GPBUnknownField alloc] initWithNumber:4] autorelease]; + [field addFixed32:6]; + [set1 addField:field]; + field = [[[GPBUnknownField alloc] initWithNumber:5] autorelease]; + [field addFixed64:20]; + [set1 addField:field]; field = [[[GPBUnknownField alloc] initWithNumber:10] autorelease]; [field addLengthDelimited:DataFromCStr("data1")]; [set1 addField:field]; + GPBUnknownFieldSet *group1 = [[[GPBUnknownFieldSet alloc] init] autorelease]; + GPBUnknownField* fieldGroup1 = [[[GPBUnknownField alloc] initWithNumber:200] autorelease]; + [fieldGroup1 addVarint:100]; + [group1 addField:fieldGroup1]; + + field = [[[GPBUnknownField alloc] initWithNumber:11] autorelease]; + [field addGroup:group1]; + [set1 addField:field]; + GPBUnknownFieldSet* set2 = [[[GPBUnknownFieldSet alloc] init] autorelease]; field = [[[GPBUnknownField alloc] initWithNumber:1] autorelease]; [field addVarint:1]; @@ -127,10 +231,25 @@ static NSData *DataFromCStr(const char *str) { field = [[[GPBUnknownField alloc] initWithNumber:3] autorelease]; [field addVarint:3]; [set2 addField:field]; + field = [[[GPBUnknownField alloc] initWithNumber:4] autorelease]; + [field addFixed32:7]; + [set2 addField:field]; + field = [[[GPBUnknownField alloc] initWithNumber:5] autorelease]; + [field addFixed64:30]; + [set2 addField:field]; field = [[[GPBUnknownField alloc] initWithNumber:10] autorelease]; [field addLengthDelimited:DataFromCStr("data2")]; [set2 addField:field]; + GPBUnknownFieldSet *group2 = [[[GPBUnknownFieldSet alloc] init] autorelease]; + GPBUnknownField* fieldGroup2 = [[[GPBUnknownField alloc] initWithNumber:201] autorelease]; + [fieldGroup2 addVarint:99]; + [group2 addField:fieldGroup2]; + + field = [[[GPBUnknownField alloc] initWithNumber:11] autorelease]; + [field addGroup:group2]; + [set2 addField:field]; + GPBUnknownFieldSet* set3 = [[[GPBUnknownFieldSet alloc] init] autorelease]; field = [[[GPBUnknownField alloc] initWithNumber:1] autorelease]; [field addVarint:1]; @@ -143,11 +262,33 @@ static NSData *DataFromCStr(const char *str) { [set3 addField:field]; [field addVarint:3]; [set3 addField:field]; + field = [[[GPBUnknownField alloc] initWithNumber:4] autorelease]; + [field addFixed32:6]; + [field addFixed32:7]; + [set3 addField:field]; + field = [[[GPBUnknownField alloc] initWithNumber:5] autorelease]; + [field addFixed64:20]; + [field addFixed64:30]; + [set3 addField:field]; field = [[[GPBUnknownField alloc] initWithNumber:10] autorelease]; [field addLengthDelimited:DataFromCStr("data1")]; [field addLengthDelimited:DataFromCStr("data2")]; [set3 addField:field]; + GPBUnknownFieldSet *group3a = [[[GPBUnknownFieldSet alloc] init] autorelease]; + GPBUnknownField* fieldGroup3a1 = [[[GPBUnknownField alloc] initWithNumber:200] autorelease]; + [fieldGroup3a1 addVarint:100]; + [group3a addField:fieldGroup3a1]; + GPBUnknownFieldSet *group3b = [[[GPBUnknownFieldSet alloc] init] autorelease]; + GPBUnknownField* fieldGroup3b2 = [[[GPBUnknownField alloc] initWithNumber:201] autorelease]; + [fieldGroup3b2 addVarint:99]; + [group3b addField:fieldGroup3b2]; + + field = [[[GPBUnknownField alloc] initWithNumber:11] autorelease]; + [field addGroup:group1]; + [field addGroup:group3b]; + [set3 addField:field]; + TestEmptyMessage* source1 = [TestEmptyMessage message]; [source1 setUnknownFields:set1]; TestEmptyMessage* source2 = [TestEmptyMessage message]; @@ -250,6 +391,107 @@ static NSData *DataFromCStr(const char *str) { XCTAssertEqual(0x7FFFFFFFFFFFFFFFULL, [field2.varintList valueAtIndex:0]); } +#pragma mark - Field tests +// Some tests directly on fields since the dictionary in FieldSet can gate +// testing some of these. + +- (void)testFieldEqualityAndHash { + GPBUnknownField* field1 = [[[GPBUnknownField alloc] initWithNumber:1] autorelease]; + XCTAssertTrue([field1 isEqual:field1]); + XCTAssertFalse([field1 isEqual:@"foo"]); + GPBUnknownField* field2 = [[[GPBUnknownField alloc] initWithNumber:2] autorelease]; + XCTAssertNotEqualObjects(field1, field2); + + field2 = [[[GPBUnknownField alloc] initWithNumber:1] autorelease]; + XCTAssertEqualObjects(field1, field2); + XCTAssertEqual([field1 hash], [field2 hash]); + + // Varint + + [field1 addVarint:10]; + XCTAssertNotEqualObjects(field1, field2); + [field2 addVarint:10]; + XCTAssertEqualObjects(field1, field2); + XCTAssertEqual([field1 hash], [field2 hash]); + [field1 addVarint:11]; + XCTAssertNotEqualObjects(field1, field2); + [field2 addVarint:11]; + XCTAssertEqualObjects(field1, field2); + XCTAssertEqual([field1 hash], [field2 hash]); + + // Fixed32 + + [field1 addFixed32:20]; + XCTAssertNotEqualObjects(field1, field2); + [field2 addFixed32:20]; + XCTAssertEqualObjects(field1, field2); + XCTAssertEqual([field1 hash], [field2 hash]); + [field1 addFixed32:21]; + XCTAssertNotEqualObjects(field1, field2); + [field2 addFixed32:21]; + XCTAssertEqualObjects(field1, field2); + XCTAssertEqual([field1 hash], [field2 hash]); + + // Fixed64 + + [field1 addFixed64:30]; + XCTAssertNotEqualObjects(field1, field2); + [field2 addFixed64:30]; + XCTAssertEqualObjects(field1, field2); + XCTAssertEqual([field1 hash], [field2 hash]); + [field1 addFixed64:31]; + XCTAssertNotEqualObjects(field1, field2); + [field2 addFixed64:31]; + XCTAssertEqualObjects(field1, field2); + XCTAssertEqual([field1 hash], [field2 hash]); + + // LengthDelimited + + [field1 addLengthDelimited:DataFromCStr("foo")]; + XCTAssertNotEqualObjects(field1, field2); + [field2 addLengthDelimited:DataFromCStr("foo")]; + XCTAssertEqualObjects(field1, field2); + XCTAssertEqual([field1 hash], [field2 hash]); + [field1 addLengthDelimited:DataFromCStr("bar")]; + XCTAssertNotEqualObjects(field1, field2); + [field2 addLengthDelimited:DataFromCStr("bar")]; + XCTAssertEqualObjects(field1, field2); + XCTAssertEqual([field1 hash], [field2 hash]); + + // Group + + GPBUnknownFieldSet *group = [[[GPBUnknownFieldSet alloc] init] autorelease]; + GPBUnknownField* fieldGroup = [[[GPBUnknownField alloc] initWithNumber:100] autorelease]; + [fieldGroup addVarint:100]; + [group addField:fieldGroup]; + [field1 addGroup:group]; + XCTAssertNotEqualObjects(field1, field2); + group = [[[GPBUnknownFieldSet alloc] init] autorelease]; + fieldGroup = [[[GPBUnknownField alloc] initWithNumber:100] autorelease]; + [fieldGroup addVarint:100]; + [group addField:fieldGroup]; + [field2 addGroup:group]; + XCTAssertEqualObjects(field1, field2); + XCTAssertEqual([field1 hash], [field2 hash]); + + group = [[[GPBUnknownFieldSet alloc] init] autorelease]; + fieldGroup = [[[GPBUnknownField alloc] initWithNumber:101] autorelease]; + [fieldGroup addVarint:101]; + [group addField:fieldGroup]; + [field1 addGroup:group]; + XCTAssertNotEqualObjects(field1, field2); + group = [[[GPBUnknownFieldSet alloc] init] autorelease]; + fieldGroup = [[[GPBUnknownField alloc] initWithNumber:101] autorelease]; + [fieldGroup addVarint:101]; + [group addField:fieldGroup]; + [field2 addGroup:group]; + XCTAssertEqualObjects(field1, field2); + XCTAssertEqual([field1 hash], [field2 hash]); + + // Exercise description for completeness. + XCTAssertTrue(field1.description.length > 10); +} + - (void)testMergingFields { GPBUnknownField* field1 = [[[GPBUnknownField alloc] initWithNumber:1] autorelease]; [field1 addVarint:1]; @@ -257,9 +499,8 @@ static NSData *DataFromCStr(const char *str) { [field1 addFixed64:3]; [field1 addLengthDelimited:[NSData dataWithBytes:"hello" length:5]]; [field1 addGroup:[[unknownFields_ copy] autorelease]]; - GPBUnknownField* field2 = [[[GPBUnknownField alloc] initWithNumber:2] autorelease]; + GPBUnknownField* field2 = [[[GPBUnknownField alloc] initWithNumber:1] autorelease]; [field2 mergeFromField:field1]; - XCTAssertEqualObjects(field1, field2); } @end