aboutsummaryrefslogtreecommitdiffhomepage
path: root/objectivec/Tests/GPBMessageTests.m
diff options
context:
space:
mode:
Diffstat (limited to 'objectivec/Tests/GPBMessageTests.m')
-rw-r--r--objectivec/Tests/GPBMessageTests.m285
1 files changed, 246 insertions, 39 deletions
diff --git a/objectivec/Tests/GPBMessageTests.m b/objectivec/Tests/GPBMessageTests.m
index 5ec67cd9..e0154c1a 100644
--- a/objectivec/Tests/GPBMessageTests.m
+++ b/objectivec/Tests/GPBMessageTests.m
@@ -34,6 +34,7 @@
#import "GPBArray_PackagePrivate.h"
#import "GPBDescriptor.h"
+#import "GPBDictionary_PackagePrivate.h"
#import "GPBField_PackagePrivate.h"
#import "GPBMessage_PackagePrivate.h"
#import "GPBUnknownFieldSet_PackagePrivate.h"
@@ -47,23 +48,9 @@
@implementation MessageTests
// TODO(thomasvl): this should get split into a few files of logic junks, it is
-// a jumble
-// of things at the moment (and the testutils have a bunch of the real
+// a jumble of things at the moment (and the testutils have a bunch of the real
// assertions).
-#ifdef DEBUG
-- (void)assertBlock:(void (^)())block
- throwsWithMessageInUserInfo:(GPBMessage *)message {
- @try {
- block();
- XCTAssertTrue(NO);
- }
- @catch (NSException *e) {
- XCTAssertEqualObjects([e userInfo][GPBExceptionMessageKey], message);
- }
-}
-#endif // DEBUG
-
- (TestAllTypes *)mergeSource {
TestAllTypes *message = [TestAllTypes message];
[message setOptionalInt32:1];
@@ -290,14 +277,18 @@
XCTAssertTrue(message.initialized);
}
-#ifdef DEBUG
-- (void)testUninitializedException {
+- (void)testDataFromUninitialized {
TestRequired *message = [TestRequired message];
- [self assertBlock:^{
- [message data];
- } throwsWithMessageInUserInfo:message];
-}
+ NSData *data = [message data];
+ // In DEBUG, the data generation will fail, but in non DEBUG, it passes
+ // because the check isn't done (for speed).
+#ifdef DEBUG
+ XCTAssertNil(data);
+#else
+ XCTAssertNotNil(data);
+ XCTAssertFalse(message.initialized);
#endif // DEBUG
+}
- (void)testInitialized {
// We're mostly testing that no exception is thrown.
@@ -305,18 +296,22 @@
XCTAssertFalse(message.initialized);
}
-#ifdef DEBUG
-- (void)testNestedUninitializedException {
+- (void)testDataFromNestedUninitialized {
TestRequiredForeign *message = [TestRequiredForeign message];
[message setOptionalMessage:[TestRequired message]];
message.repeatedMessageArray = [NSMutableArray array];
[message.repeatedMessageArray addObject:[TestRequired message]];
[message.repeatedMessageArray addObject:[TestRequired message]];
- [self assertBlock:^{
- [message data];
- } throwsWithMessageInUserInfo:message];
-}
+ NSData *data = [message data];
+ // In DEBUG, the data generation will fail, but in non DEBUG, it passes
+ // because the check isn't done (for speed).
+#ifdef DEBUG
+ XCTAssertNil(data);
+#else
+ XCTAssertNotNil(data);
+ XCTAssertFalse(message.initialized);
#endif // DEBUG
+}
- (void)testNestedInitialized {
// We're mostly testing that no exception is thrown.
@@ -330,13 +325,23 @@
XCTAssertFalse(message.initialized);
}
-#ifdef DEBUG
- (void)testParseUninitialized {
- [self assertBlock:^{
- [TestRequired parseFromData:GPBEmptyNSData()];
- } throwsWithMessageInUserInfo:[TestRequired message]];
-}
+ NSError *error = nil;
+ TestRequired *msg =
+ [TestRequired parseFromData:GPBEmptyNSData() error:&error];
+ // In DEBUG, the parse will fail, but in non DEBUG, it passes because
+ // the check isn't done (for speed).
+#ifdef DEBUG
+ XCTAssertNil(msg);
+ XCTAssertNotNil(error);
+ XCTAssertEqualObjects(error.domain, GPBMessageErrorDomain);
+ XCTAssertEqual(error.code, GPBMessageErrorCodeMissingRequiredField);
+#else
+ XCTAssertNotNil(msg);
+ XCTAssertNil(error);
+ XCTAssertFalse(msg.initialized);
#endif // DEBUG
+}
- (void)testCoding {
NSData *data =
@@ -1033,7 +1038,7 @@
message3.repeatedStringArray = [NSMutableArray arrayWithObject:@"wee"];
XCTAssertNotNil(message.repeatedInt32Array);
XCTAssertNotNil(message.repeatedStringArray);
- TestAllTypes *message4 = [message3 copy];
+ TestAllTypes *message4 = [[message3 copy] autorelease];
XCTAssertNotEqual(message3.repeatedInt32Array, message4.repeatedInt32Array);
XCTAssertEqualObjects(message3.repeatedInt32Array,
message4.repeatedInt32Array);
@@ -1156,6 +1161,205 @@
XCTAssertFalse([message hasA]);
}
+- (void)testDefaultingMaps {
+ // Basic tests for default creation of maps in a message.
+ TestRecursiveMessageWithRepeatedField *message =
+ [TestRecursiveMessageWithRepeatedField message];
+ TestRecursiveMessageWithRepeatedField *message2 =
+ [TestRecursiveMessageWithRepeatedField message];
+
+ // Simply accessing the map should not make any fields visible.
+ XCTAssertNotNil(message.a.a.iToI);
+ XCTAssertFalse([message hasA]);
+ XCTAssertFalse([message.a hasA]);
+ XCTAssertNotNil(message2.a.a.strToStr);
+ XCTAssertFalse([message2 hasA]);
+ XCTAssertFalse([message2.a hasA]);
+
+ // But adding an element to the map should.
+ [message.a.a.iToI setValue:100 forKey:200];
+ XCTAssertTrue([message hasA]);
+ XCTAssertTrue([message.a hasA]);
+ XCTAssertEqual([message.a.a.iToI count], (NSUInteger)1);
+ [message2.a.a.strToStr setObject:@"foo" forKey:@"bar"];
+ XCTAssertTrue([message2 hasA]);
+ XCTAssertTrue([message2.a hasA]);
+ XCTAssertEqual([message2.a.a.strToStr count], (NSUInteger)1);
+}
+
+- (void)testAutocreatedMapShared {
+ // Multiple objects pointing to the same map.
+ TestRecursiveMessageWithRepeatedField *message1a =
+ [TestRecursiveMessageWithRepeatedField message];
+ TestRecursiveMessageWithRepeatedField *message1b =
+ [TestRecursiveMessageWithRepeatedField message];
+ message1a.a.iToI = message1b.a.iToI;
+ XCTAssertTrue([message1a hasA]);
+ XCTAssertFalse([message1b hasA]);
+ [message1a.a.iToI setValue:1 forKey:2];
+ XCTAssertTrue([message1a hasA]);
+ XCTAssertTrue([message1b hasA]);
+ XCTAssertEqual(message1a.a.iToI, message1b.a.iToI);
+
+ TestRecursiveMessageWithRepeatedField *message2a =
+ [TestRecursiveMessageWithRepeatedField message];
+ TestRecursiveMessageWithRepeatedField *message2b =
+ [TestRecursiveMessageWithRepeatedField message];
+ message2a.a.strToStr = message2b.a.strToStr;
+ XCTAssertTrue([message2a hasA]);
+ XCTAssertFalse([message2b hasA]);
+ [message2a.a.strToStr setObject:@"bar" forKey:@"foo"];
+ XCTAssertTrue([message2a hasA]);
+ XCTAssertTrue([message2b hasA]);
+ XCTAssertEqual(message2a.a.strToStr, message2b.a.strToStr);
+}
+
+- (void)testAutocreatedMapCopy {
+ // Copy should not copy autocreated maps.
+ TestRecursiveMessageWithRepeatedField *message =
+ [TestRecursiveMessageWithRepeatedField message];
+ XCTAssertNotNil(message.strToStr);
+ XCTAssertNotNil(message.iToI);
+ TestRecursiveMessageWithRepeatedField *message2 =
+ [[message copy] autorelease];
+ // Pointer conparisions.
+ XCTAssertNotEqual(message.strToStr, message2.strToStr);
+ XCTAssertNotEqual(message.iToI, message2.iToI);
+
+ // Mutable copy should copy empty arrays that were explicitly set (end up
+ // with different objects that are equal).
+ TestRecursiveMessageWithRepeatedField *message3 =
+ [TestRecursiveMessageWithRepeatedField message];
+ message3.iToI = [GPBInt32Int32Dictionary dictionaryWithValue:10 forKey:20];
+ message3.strToStr =
+ [NSMutableDictionary dictionaryWithObject:@"abc" forKey:@"123"];
+ XCTAssertNotNil(message.iToI);
+ XCTAssertNotNil(message.iToI);
+ TestRecursiveMessageWithRepeatedField *message4 =
+ [[message3 copy] autorelease];
+ XCTAssertNotEqual(message3.iToI, message4.iToI);
+ XCTAssertEqualObjects(message3.iToI, message4.iToI);
+ XCTAssertNotEqual(message3.strToStr, message4.strToStr);
+ XCTAssertEqualObjects(message3.strToStr, message4.strToStr);
+}
+
+- (void)testAutocreatedMapRetain {
+ // Should be able to retain autocreated map while the creator is dealloced.
+ TestRecursiveMessageWithRepeatedField *message =
+ [TestRecursiveMessageWithRepeatedField message];
+
+ @autoreleasepool {
+ TestRecursiveMessageWithRepeatedField *message2 =
+ [TestRecursiveMessageWithRepeatedField message];
+ message.iToI = message2.iToI;
+ message.strToStr = message2.strToStr;
+ // Pointer conparision
+ XCTAssertEqual(message.iToI->_autocreator, message2);
+ XCTAssertTrue([message.strToStr
+ isKindOfClass:[GPBAutocreatedDictionary class]]);
+ XCTAssertEqual(
+ ((GPBAutocreatedDictionary *)message.strToStr)->_autocreator,
+ message2);
+ }
+
+ XCTAssertNil(message.iToI->_autocreator);
+ XCTAssertTrue(
+ [message.strToStr isKindOfClass:[GPBAutocreatedDictionary class]]);
+ XCTAssertNil(
+ ((GPBAutocreatedDictionary *)message.strToStr)->_autocreator);
+}
+
+- (void)testSetNilAutocreatedMap {
+ // Setting map to nil should cause it to lose its delegate.
+ TestRecursiveMessageWithRepeatedField *message =
+ [TestRecursiveMessageWithRepeatedField message];
+ GPBInt32Int32Dictionary *iToI = [message.iToI retain];
+ GPBAutocreatedDictionary *strToStr =
+ (GPBAutocreatedDictionary *)[message.strToStr retain];
+ XCTAssertTrue([strToStr isKindOfClass:[GPBAutocreatedDictionary class]]);
+ XCTAssertEqual(iToI->_autocreator, message);
+ XCTAssertEqual(strToStr->_autocreator, message);
+ message.iToI = nil;
+ message.strToStr = nil;
+ XCTAssertNil(iToI->_autocreator);
+ XCTAssertNil(strToStr->_autocreator);
+ [iToI release];
+ [strToStr release];
+}
+
+- (void)testReplaceAutocreatedMap {
+ // Replacing map should orphan the old one and cause its creator to become
+ // visible.
+ {
+ TestRecursiveMessageWithRepeatedField *message =
+ [TestRecursiveMessageWithRepeatedField message];
+ XCTAssertNotNil(message.a);
+ XCTAssertNotNil(message.a.iToI);
+ XCTAssertFalse([message hasA]);
+ GPBInt32Int32Dictionary *iToI = [message.a.iToI retain];
+ XCTAssertEqual(iToI->_autocreator, message.a); // Pointer comparision
+ message.a.iToI = [GPBInt32Int32Dictionary dictionaryWithValue:6 forKey:7];
+ XCTAssertTrue([message hasA]);
+ XCTAssertNotEqual(message.a.iToI, iToI); // Pointer comparision
+ XCTAssertNil(iToI->_autocreator);
+ [iToI release];
+ }
+
+ {
+ TestRecursiveMessageWithRepeatedField *message =
+ [TestRecursiveMessageWithRepeatedField message];
+ XCTAssertNotNil(message.a);
+ XCTAssertNotNil(message.a.strToStr);
+ XCTAssertFalse([message hasA]);
+ GPBAutocreatedDictionary *strToStr =
+ (GPBAutocreatedDictionary *)[message.a.strToStr retain];
+ XCTAssertTrue([strToStr isKindOfClass:[GPBAutocreatedDictionary class]]);
+ XCTAssertEqual(strToStr->_autocreator, message.a); // Pointer comparision
+ message.a.strToStr =
+ [NSMutableDictionary dictionaryWithObject:@"abc" forKey:@"def"];
+ XCTAssertTrue([message hasA]);
+ XCTAssertNotEqual(message.a.strToStr, strToStr); // Pointer comparision
+ XCTAssertNil(strToStr->_autocreator);
+ [strToStr release];
+ }
+}
+
+- (void)testSetAutocreatedMapToSelf {
+ // Setting map to itself should cause it to become visible.
+ {
+ TestRecursiveMessageWithRepeatedField *message =
+ [TestRecursiveMessageWithRepeatedField message];
+ XCTAssertNotNil(message.a);
+ XCTAssertNotNil(message.a.iToI);
+ XCTAssertFalse([message hasA]);
+ message.a.iToI = message.a.iToI;
+ XCTAssertTrue([message hasA]);
+ XCTAssertNil(message.a.iToI->_autocreator);
+ }
+
+ {
+ TestRecursiveMessageWithRepeatedField *message =
+ [TestRecursiveMessageWithRepeatedField message];
+ XCTAssertNotNil(message.a);
+ XCTAssertNotNil(message.a.strToStr);
+ XCTAssertFalse([message hasA]);
+ message.a.strToStr = message.a.strToStr;
+ XCTAssertTrue([message hasA]);
+ XCTAssertTrue([message.a.strToStr isKindOfClass:[GPBAutocreatedDictionary class]]);
+ XCTAssertNil(((GPBAutocreatedDictionary *)message.a.strToStr)->_autocreator);
+ }
+}
+
+- (void)testAutocreatedMapRemoveAllValues {
+ // Calling removeAll on autocreated map should not cause it to be visible.
+ TestRecursiveMessageWithRepeatedField *message =
+ [TestRecursiveMessageWithRepeatedField message];
+ [message.a.iToI removeAll];
+ XCTAssertFalse([message hasA]);
+ [message.a.strToStr removeAllObjects];
+ XCTAssertFalse([message hasA]);
+}
+
- (void)testExtensionAccessors {
TestAllExtensions *message = [TestAllExtensions message];
[self setAllExtensions:message repeatedCount:kGPBDefaultRepeatCount];
@@ -1555,7 +1759,8 @@
GPBMessage *message = [GPBMessage message];
[message setUnknownFields:unknowns];
NSData *data = [message data];
- GPBMessage *message2 = [GPBMessage parseFromData:data extensionRegistry:nil];
+ GPBMessage *message2 =
+ [GPBMessage parseFromData:data extensionRegistry:nil error:NULL];
XCTAssertEqualObjects(message, message2);
}
@@ -1579,9 +1784,11 @@
GPBCodedInputStream *input =
[GPBCodedInputStream streamWithData:delimitedData];
GPBMessage *message3 = [GPBMessage parseDelimitedFromCodedInputStream:input
- extensionRegistry:nil];
+ extensionRegistry:nil
+ error:NULL];
GPBMessage *message4 = [GPBMessage parseDelimitedFromCodedInputStream:input
- extensionRegistry:nil];
+ extensionRegistry:nil
+ error:NULL];
XCTAssertEqualObjects(message1, message3);
XCTAssertEqualObjects(message2, message4);
}
@@ -1673,7 +1880,7 @@
XCTAssertEqual(msg.bar, EnumTestMsg_MyEnum_One);
XCTAssertEqual(msg.baz, EnumTestMsg_MyEnum_NegOne);
// Bounce to wire and back.
- EnumTestMsg *msgPrime = [EnumTestMsg parseFromData:[msg data]];
+ EnumTestMsg *msgPrime = [EnumTestMsg parseFromData:[msg data] error:NULL];
XCTAssertEqualObjects(msgPrime, msg);
XCTAssertEqual(msgPrime.foo, EnumTestMsg_MyEnum_Zero);
XCTAssertEqual(msgPrime.bar, EnumTestMsg_MyEnum_One);
@@ -1685,7 +1892,7 @@
XCTAssertEqual(msg.bar, EnumTestMsg_MyEnum_Two);
XCTAssertEqual(msg.baz, EnumTestMsg_MyEnum_NegTwo);
// Bounce to wire and back.
- msgPrime = [EnumTestMsg parseFromData:[msg data]];
+ msgPrime = [EnumTestMsg parseFromData:[msg data] error:NULL];
XCTAssertEqualObjects(msgPrime, msg);
XCTAssertEqual(msgPrime.foo, EnumTestMsg_MyEnum_Zero);
XCTAssertEqual(msgPrime.bar, EnumTestMsg_MyEnum_Two);
@@ -1706,7 +1913,7 @@
XCTAssertEqual([msg.mumbleArray valueAtIndex:3], EnumTestMsg_MyEnum_NegOne);
XCTAssertEqual([msg.mumbleArray valueAtIndex:4], EnumTestMsg_MyEnum_NegTwo);
// Bounce to wire and back.
- msgPrime = [EnumTestMsg parseFromData:[msg data]];
+ msgPrime = [EnumTestMsg parseFromData:[msg data] error:NULL];
XCTAssertEqualObjects(msgPrime, msg);
XCTAssertEqual([msgPrime.mumbleArray valueAtIndex:0],
EnumTestMsg_MyEnum_Zero);