Add basic KVO test.

Add a simple KVO test just to verify that KVO continues to function for protobufs.
This commit is contained in:
Dave MacLachlan 2021-06-11 14:17:01 -07:00 committed by Thomas Van Lenten
parent d1ef6d9826
commit 36e9bfc963

View File

@ -41,6 +41,52 @@
#import "google/protobuf/Unittest.pbobjc.h"
#import "google/protobuf/UnittestObjc.pbobjc.h"
#import "google/protobuf/UnittestObjcOptions.pbobjc.h"
#import "google/protobuf/UnittestImport.pbobjc.h"
// Helper class to test KVO.
@interface GPBKVOTestObserver : NSObject {
id observee_;
NSString *keyPath_;
}
@property (nonatomic) BOOL didObserve;
- (id)initWithObservee:(id)observee keyPath:(NSString *)keyPath;
@end
@implementation GPBKVOTestObserver
@synthesize didObserve;
- (id)initWithObservee:(id)observee keyPath:(NSString *)keyPath {
if (self = [super init]) {
observee_ = [observee retain];
keyPath_ = [keyPath copy];
[observee_ addObserver:self forKeyPath:keyPath_ options:0 context:NULL];
}
return self;
}
- (void)dealloc {
[observee_ removeObserver:self forKeyPath:keyPath_];
[observee_ release];
[keyPath_ release];
[super dealloc];
}
- (void)observeValueForKeyPath:(NSString *)keyPath
ofObject:(id)object
change:(NSDictionary *)change
context:(void *)context
{
#pragma unused(object)
#pragma unused(change)
#pragma unused(context)
if ([keyPath isEqualToString:keyPath_]) {
self.didObserve = YES;
}
}
@end
@interface MessageTests : GPBTestCase
@end
@ -431,6 +477,55 @@
[self assertAllFieldsKVCMatch:message];
}
- (void)testKVOBasic {
TestAllTypes *message = [TestAllTypes message];
GPBKVOTestObserver *observer =
[[[GPBKVOTestObserver alloc] initWithObservee:message
keyPath:@"optionalString"]
autorelease];
XCTAssertFalse(observer.didObserve);
message.defaultString = @"Hello";
XCTAssertFalse(observer.didObserve);
message.optionalString = @"Hello";
XCTAssertTrue(observer.didObserve);
}
- (void)testKVOAutocreate {
TestAllTypes *message = [TestAllTypes message];
GPBKVOTestObserver *autocreateObserver =
[[[GPBKVOTestObserver alloc] initWithObservee:message
keyPath:@"optionalImportMessage"]
autorelease];
GPBKVOTestObserver *innerFieldObserver =
[[[GPBKVOTestObserver alloc] initWithObservee:message
keyPath:@"optionalImportMessage.d"]
autorelease];
XCTAssertFalse(autocreateObserver.didObserve);
XCTAssertFalse(innerFieldObserver.didObserve);
int a = message.optionalImportMessage.d;
XCTAssertEqual(a, 0);
// Autocreation of fields is not observed by KVO when getting values.
XCTAssertFalse(autocreateObserver.didObserve);
XCTAssertFalse(innerFieldObserver.didObserve);
message.optionalImportMessage.d = 2;
// Autocreation of fields is not observed by KVO.
// This is undefined behavior. The library makes no guarantees with regards
// to KVO firing if an autocreation occurs as part of a setter.
// This test exists just to be aware if the behavior changes.
XCTAssertFalse(autocreateObserver.didObserve);
// Values set inside of an autocreated field are observed.
XCTAssertTrue(innerFieldObserver.didObserve);
// Explicit setting of a message field is observed.
message.optionalImportMessage = [ImportMessage message];
XCTAssertTrue(autocreateObserver.didObserve);
}
- (void)testDescription {
// No real test, just exercise code
TestAllTypes *message = [TestAllTypes message];