[ObjC] Add test around enum unknown values.

PiperOrigin-RevId: 654858735
pull/17587/head
Thomas Van Lenten 4 months ago
parent cf7abf6c6b
commit fad7b78e1a
  1. 52
      objectivec/Tests/GPBMessageTests.m
  2. 187
      objectivec/Tests/unittest_objc.proto

@ -5,14 +5,14 @@
// license that can be found in the LICENSE file or at // license that can be found in the LICENSE file or at
// https://developers.google.com/open-source/licenses/bsd // https://developers.google.com/open-source/licenses/bsd
#import "GPBTestUtilities.h"
#import <objc/runtime.h> #import <objc/runtime.h>
#import "GPBArray.h"
#import "GPBArray_PackagePrivate.h" #import "GPBArray_PackagePrivate.h"
#import "GPBDescriptor.h" #import "GPBDescriptor.h"
#import "GPBDictionary_PackagePrivate.h" #import "GPBDictionary_PackagePrivate.h"
#import "GPBMessage_PackagePrivate.h" #import "GPBMessage_PackagePrivate.h"
#import "GPBTestUtilities.h"
#import "GPBUnknownFieldSet_PackagePrivate.h" #import "GPBUnknownFieldSet_PackagePrivate.h"
#import "GPBUnknownField_PackagePrivate.h" #import "GPBUnknownField_PackagePrivate.h"
#import "objectivec/Tests/Unittest.pbobjc.h" #import "objectivec/Tests/Unittest.pbobjc.h"
@ -2022,6 +2022,54 @@
XCTAssertEqual([msgPrime.mumbleArray valueAtIndex:4], EnumTestMsg_MyEnum_NegTwo); XCTAssertEqual([msgPrime.mumbleArray valueAtIndex:4], EnumTestMsg_MyEnum_NegTwo);
} }
- (void)testCloseEnumsValuesOutOfRange {
// The unknown values should all make it into the unknown fields.
EnumTestMsg *msg1 = [EnumTestMsg message];
msg1.bar = EnumTestMsg_MyEnum_NegTwo;
msg1.baz = EnumTestMsg_MyEnum_Two;
[msg1.mumbleArray addValue:EnumTestMsg_MyEnum_Two];
[msg1.mumbleArray addValue:EnumTestMsg_MyEnum_NegTwo];
NSData *data = [msg1 data];
XCTAssertNotNil(data);
EnumTestMsgPrime *msg2 = [EnumTestMsgPrime parseFromData:data error:NULL];
XCTAssertNotNil(msg2);
XCTAssertEqualObjects(data, [msg2 data]);
XCTAssertFalse(msg2.hasBar);
XCTAssertFalse(msg2.hasBaz);
XCTAssertEqual(msg2.mumbleArray_Count, 0U);
GPBUnknownFields *ufs = [[[GPBUnknownFields alloc] initFromMessage:msg2] autorelease];
XCTAssertEqual(ufs.count, 4U);
uint64_t varint;
XCTAssertTrue([ufs getFirst:EnumTestMsg_FieldNumber_Bar varint:&varint]);
XCTAssertEqual(varint, (uint64_t)EnumTestMsg_MyEnum_NegTwo);
XCTAssertTrue([ufs getFirst:EnumTestMsg_FieldNumber_Baz varint:&varint]);
XCTAssertEqual(varint, (uint64_t)EnumTestMsg_MyEnum_Two);
NSArray<GPBUnknownField *> *fields = [ufs fields:EnumTestMsg_FieldNumber_MumbleArray];
XCTAssertEqual(fields.count, 2U);
XCTAssertEqual(fields[0].varint, (uint64_t)EnumTestMsg_MyEnum_Two);
XCTAssertEqual(fields[1].varint, (uint64_t)EnumTestMsg_MyEnum_NegTwo);
GPBUnknownFieldSet *unknownFields = msg2.unknownFields;
XCTAssertNotNil(unknownFields);
XCTAssertEqual(unknownFields.countOfFields, 3U);
XCTAssertTrue([unknownFields hasField:EnumTestMsg_FieldNumber_Bar]);
XCTAssertTrue([unknownFields hasField:EnumTestMsg_FieldNumber_Baz]);
XCTAssertTrue([unknownFields hasField:EnumTestMsg_FieldNumber_MumbleArray]);
GPBUnknownField *field = [unknownFields getField:EnumTestMsg_FieldNumber_Bar];
XCTAssertEqual(field.varintList.count, 1U);
XCTAssertEqual([field.varintList valueAtIndex:0], (uint64_t)EnumTestMsg_MyEnum_NegTwo);
field = [unknownFields getField:EnumTestMsg_FieldNumber_Baz];
XCTAssertEqual(field.varintList.count, 1U);
XCTAssertEqual([field.varintList valueAtIndex:0], (uint64_t)EnumTestMsg_MyEnum_Two);
field = [unknownFields getField:EnumTestMsg_FieldNumber_MumbleArray];
XCTAssertEqual(field.varintList.count, 2U);
XCTAssertEqual([field.varintList valueAtIndex:0], (uint64_t)EnumTestMsg_MyEnum_Two);
XCTAssertEqual([field.varintList valueAtIndex:1], (uint64_t)EnumTestMsg_MyEnum_NegTwo);
}
- (void)testReservedWordNaming { - (void)testReservedWordNaming {
// names.cc has some special handing to make sure that some "reserved" objc // names.cc has some special handing to make sure that some "reserved" objc
// names get renamed in a way so they don't conflict. // names get renamed in a way so they don't conflict.

@ -7,11 +7,11 @@
syntax = "proto2"; syntax = "proto2";
package objc.protobuf.tests;
import "google/protobuf/any.proto"; import "google/protobuf/any.proto";
import "objectivec/Tests/unittest.proto"; import "objectivec/Tests/unittest.proto";
package objc.protobuf.tests;
// Explicit empty prefix, tests some validations code paths also. // Explicit empty prefix, tests some validations code paths also.
option objc_class_prefix = ""; option objc_class_prefix = "";
@ -78,143 +78,142 @@ message self {
} }
enum autorelease { enum autorelease {
retain = 1; retain = 1;
release = 2; release = 2;
retainCount = 3; retainCount = 3;
} }
// Singular // Singular
// Objective C Keywords // Objective C Keywords
optional bool id = 1; optional bool id = 1;
optional bool _cmd = 2; optional bool _cmd = 2;
// super is used as submessage above // super is used as submessage above
optional bool in = 4; optional bool in = 4;
optional bool out = 5; optional bool out = 5;
optional bool inout = 6; optional bool inout = 6;
optional bool bycopy = 7; optional bool bycopy = 7;
optional bool byref = 8; optional bool byref = 8;
optional bool oneway = 9; optional bool oneway = 9;
optional bool self = 10; optional bool self = 10;
optional bool instancetype = 11; optional bool instancetype = 11;
optional bool nullable = 12; optional bool nullable = 12;
optional bool nonnull = 13; optional bool nonnull = 13;
optional bool nil = 14; optional bool nil = 14;
// Nil and nil can't be in the same message // Nil and nil can't be in the same message
optional bool YES = 16; optional bool YES = 16;
optional bool NO = 17; optional bool NO = 17;
optional bool weak = 18; optional bool weak = 18;
// Some C/C++ Keywords // Some C/C++ Keywords
optional bool case = 30; optional bool case = 30;
optional bool if = 31; optional bool if = 31;
optional bool and_eq = 32; optional bool and_eq = 32;
optional bool public = 33; optional bool public = 33;
optional bool private = 34; optional bool private = 34;
optional bool typename = 35; optional bool typename = 35;
optional bool static_cast = 36; optional bool static_cast = 36;
optional bool typeof = 37; optional bool typeof = 37;
optional bool restrict = 38; optional bool restrict = 38;
optional bool NULL = 39; optional bool NULL = 39;
// Some NSObject Methods // Some NSObject Methods
optional bool dealloc = 110; optional bool dealloc = 110;
optional bool isProxy = 111; optional bool isProxy = 111;
optional bool copy = 112; optional bool copy = 112;
optional bool description = 113; optional bool description = 113;
optional bool zone = 114; optional bool zone = 114;
optional bool className = 115; optional bool className = 115;
optional bool __retain_OA = 116; optional bool __retain_OA = 116;
optional bool CAMLType = 117; optional bool CAMLType = 117;
optional bool isNSDictionary__ = 118; optional bool isNSDictionary__ = 118;
optional bool accessibilityLabel = 119; optional bool accessibilityLabel = 119;
// Some Objc "keywords" that we shouldn't // Some Objc "keywords" that we shouldn't
// have to worry about because they // have to worry about because they
// can only appear in specialized areas. // can only appear in specialized areas.
optional bool assign = 200; optional bool assign = 200;
optional bool getter = 201; optional bool getter = 201;
optional bool setter = 202; optional bool setter = 202;
optional bool atomic = 203; optional bool atomic = 203;
optional bool nonatomic = 204; optional bool nonatomic = 204;
optional bool strong = 205; optional bool strong = 205;
optional bool null_resettable = 206; optional bool null_resettable = 206;
optional bool readonly = 207; optional bool readonly = 207;
// Some GPBMessage methods // Some GPBMessage methods
optional bool clear = 300; optional bool clear = 300;
optional bool data = 301; optional bool data = 301;
optional bool descriptor = 302; optional bool descriptor = 302;
optional bool delimitedData = 303; optional bool delimitedData = 303;
// Some MacTypes // Some MacTypes
optional bool Fixed = 400; optional bool Fixed = 400;
optional bool Point = 401; optional bool Point = 401;
optional bool FixedPoint = 402; optional bool FixedPoint = 402;
optional bool Style = 403; optional bool Style = 403;
// C/C++ reserved identifiers // C/C++ reserved identifiers
optional bool _Generic = 500; optional bool _Generic = 500;
optional bool __block = 501; optional bool __block = 501;
// Try a keyword as a type // Try a keyword as a type
optional autorelease SubEnum = 1000; optional autorelease SubEnum = 1000;
optional group New = 2000 { optional group New = 2000 {
optional string copy = 1; optional string copy = 1;
} }
optional group MutableCopy = 2001 { optional group MutableCopy = 2001 {
optional int32 extensionRegistry = 1; optional int32 extensionRegistry = 1;
} }
extensions 3000 to 3999; extensions 3000 to 3999;
} }
enum retain { enum retain {
count = 4; count = 4;
initialized = 5; initialized = 5;
serializedSize = 6; serializedSize = 6;
} }
message ObjCPropertyNaming { message ObjCPropertyNaming {
// Test that the properties properly get things all caps. // Test that the properties properly get things all caps.
optional string url = 1; optional string url = 1;
optional string thumbnail_url = 2; optional string thumbnail_url = 2;
optional string url_foo = 3; optional string url_foo = 3;
optional string some_url_blah = 4; optional string some_url_blah = 4;
optional string http = 5; optional string http = 5;
optional string https = 6; optional string https = 6;
// This one doesn't. // This one doesn't.
repeated string urls = 7; repeated string urls = 7;
} }
// EnumValueShortName: The short names shouldn't get suffixes/prefixes. // EnumValueShortName: The short names shouldn't get suffixes/prefixes.
enum Foo { enum Foo {
SERIALIZED_SIZE = 1; SERIALIZED_SIZE = 1;
SIZE = 2; SIZE = 2;
OTHER = 3; OTHER = 3;
} }
// EnumValueShortName: The enum name gets a prefix. // EnumValueShortName: The enum name gets a prefix.
enum Category { enum Category {
RED = 1; RED = 1;
BLUE = 2; BLUE = 2;
} }
// EnumValueShortName: Twist case, full name gets PB, but the short names // EnumValueShortName: Twist case, full name gets PB, but the short names
// should still end up correct. // should still end up correct.
enum Time { enum Time {
BASE = 1; BASE = 1;
RECORD = 2; RECORD = 2;
SOMETHING_ELSE = 3; SOMETHING_ELSE = 3;
} }
extend self { extend self {
repeated int32 debugDescription = 3000 [packed = true]; repeated int32 debugDescription = 3000 [packed = true];
repeated int64 finalize = 3001 [packed = true]; repeated int64 finalize = 3001 [packed = true];
repeated uint32 hash = 3002 [packed = true]; repeated uint32 hash = 3002 [packed = true];
repeated uint64 classForCoder = 3003 [packed = true]; repeated uint64 classForCoder = 3003 [packed = true];
repeated sint32 byref = 3004 [packed = true]; repeated sint32 byref = 3004 [packed = true];
} }
// Test handing of fields that start with init*. // Test handing of fields that start with init*.
@ -700,13 +699,17 @@ message JustToScopeExtensions {
repeated string mutableCopy_val_lower_complex_repeated = 2711; repeated string mutableCopy_val_lower_complex_repeated = 2711;
repeated string mutableCopy_Val_upper_complex_repeated = 2712; repeated string mutableCopy_Val_upper_complex_repeated = 2712;
repeated string mutableCopyvalue_lower_no_underscore_complex_repeated = 2713; repeated string mutableCopyvalue_lower_no_underscore_complex_repeated =
repeated string mutableCopyValue_upper_no_underscore_complex_repeated = 2714; 2713;
repeated string mutableCopyValue_upper_no_underscore_complex_repeated =
2714;
repeated int32 mutableCopy_val_lower_primitive_repeated = 2715; repeated int32 mutableCopy_val_lower_primitive_repeated = 2715;
repeated int32 mutableCopy_Val_upper_primitive_repeated = 2716; repeated int32 mutableCopy_Val_upper_primitive_repeated = 2716;
repeated int32 mutableCopyvalue_lower_no_underscore_primitive_repeated = 2717; repeated int32 mutableCopyvalue_lower_no_underscore_primitive_repeated =
repeated int32 mutableCopyValue_upper_no_underscore_primitive_repeated = 2718; 2717;
repeated int32 mutableCopyValue_upper_no_underscore_primitive_repeated =
2718;
repeated self mutableCopy_val_lower_message_repeated = 2719; repeated self mutableCopy_val_lower_message_repeated = 2719;
repeated self mutableCopy_Val_upper_message_repeated = 2720; repeated self mutableCopy_Val_upper_message_repeated = 2720;
@ -781,9 +784,9 @@ message ObjcWeirdDefaults {
// Used to confirm negative enum values work as expected. // Used to confirm negative enum values work as expected.
message EnumTestMsg { message EnumTestMsg {
enum MyEnum { enum MyEnum {
ZERO = 0; ZERO = 0;
ONE = 1; ONE = 1;
TWO = 2; TWO = 2;
NEG_ONE = -1; NEG_ONE = -1;
NEG_TWO = -2; NEG_TWO = -2;
} }
@ -794,6 +797,20 @@ message EnumTestMsg {
repeated MyEnum mumble = 4; repeated MyEnum mumble = 4;
} }
message EnumTestMsgPrime {
enum MyEnumPrime {
ZERO = 0;
ONE = 1;
NEG_ONE = -1;
// Lacks 2, -2.
}
optional MyEnumPrime foo = 1;
optional MyEnumPrime bar = 2 [default = ONE];
optional MyEnumPrime baz = 3 [default = NEG_ONE];
repeated MyEnumPrime mumble = 4;
}
// Test case for https://github.com/protocolbuffers/protobuf/issues/1453 // Test case for https://github.com/protocolbuffers/protobuf/issues/1453
// Message with no explicit defaults, but a non zero default for an enum. // Message with no explicit defaults, but a non zero default for an enum.
message MessageWithOneBasedEnum { message MessageWithOneBasedEnum {

Loading…
Cancel
Save