diff --git a/Tests/base/NSKVOSupport/basic.m b/Tests/base/NSKVOSupport/basic.m index c9685ba10..9d6389d76 100644 --- a/Tests/base/NSKVOSupport/basic.m +++ b/Tests/base/NSKVOSupport/basic.m @@ -1,23 +1,44 @@ #import #import "ObjectTesting.h" -#if defined(__OBJC2__) - @interface Foo : NSObject -@property (assign) BOOL a; -@property (assign) NSInteger b; -@property (nonatomic, strong) NSString *c; -@property (nonatomic, strong) NSArray *d; +{ +@public + BOOL a; + NSInteger b; + NSString *c; + NSArray *d; +} +- (void) setA: (BOOL)v; +- (void) setB: (NSInteger)v; +- (void) setC: (NSString *)v; @end @implementation Foo +- (void) setA: (BOOL)v +{ + a = v; +} +- (void) setB: (NSInteger)v +{ + b = v; +} +- (void) setC: (NSString *)v +{ + c = v; +} @end @interface Observer : NSObject -@property (assign) Foo *object; -@property (assign) NSString *expectedKeyPath; -@property (assign) NSInteger receivedCalls; - +{ + Foo *object; + NSString *expectedKeyPath; + NSInteger receivedCalls; +} +- (NSString*) expectedKeyPath; +- (void) setExpectedKeyPath: (NSString*)s; +- (NSInteger) receivedCalls; +- (void) setReceivedCalls: (NSInteger)i; @end @implementation Observer @@ -27,7 +48,7 @@ - (id)init self = [super init]; if (self) { - self.receivedCalls = 0; + receivedCalls = 0; } return self; } @@ -36,21 +57,38 @@ - (id)init - (void)startObserving:(Foo *)target { - self.object = target; + object = target; [target addObserver:self forKeyPath:@"a" options:0 context:&observerContext]; [target addObserver:self forKeyPath:@"b" options:0 context:&observerContext]; [target addObserver:self forKeyPath:@"c" options:0 context:&observerContext]; } - (void)observeValueForKeyPath:(NSString *)keyPath - ofObject:(id)object - change:(NSDictionary *)change + ofObject:(id)o + change:(NSDictionary *)change context:(void *)context { PASS(context == &observerContext, "context"); - PASS(object == self.object, "object"); - PASS([keyPath isEqualToString:self.expectedKeyPath], "key path"); - self.receivedCalls++; + PASS(o == self->object, "object"); + PASS([keyPath isEqualToString: [self expectedKeyPath]], "key path"); + [self setReceivedCalls: [self receivedCalls] + 1]; +} + +- (NSString*) expectedKeyPath +{ + return expectedKeyPath; +} +- (void) setExpectedKeyPath: (NSString*)s +{ + expectedKeyPath = s; +} +- (NSInteger) receivedCalls +{ + return receivedCalls; +} +- (void) setReceivedCalls: (NSInteger)i +{ + receivedCalls = i; } @end @@ -62,26 +100,21 @@ - (void)observeValueForKeyPath:(NSString *)keyPath Foo *foo = [Foo new]; Observer *obs = [Observer new]; - [obs startObserving:foo]; - obs.expectedKeyPath = @"a"; - foo.a = YES; - PASS(obs.receivedCalls == 1, "received calls") + [obs startObserving: foo]; - obs.expectedKeyPath = @"b"; - foo.b = 1; - PASS(obs.receivedCalls == 2, "received calls") + [obs setExpectedKeyPath: @"a"]; + [foo setA: YES]; + PASS([obs receivedCalls] == 1, "received calls") - obs.expectedKeyPath = @"c"; - foo.c = @"henlo"; - PASS(obs.receivedCalls == 3, "received calls") -} + [obs setExpectedKeyPath: @"b"]; + [foo setB: 1]; + PASS([obs receivedCalls] == 2, "received calls") + + [obs setExpectedKeyPath: @"c"]; + [foo setC: @"henlo"]; + PASS([obs receivedCalls] == 3, "received calls") -#else -int -main(int argc, const char *argv[]) -{ return 0; } -#endif \ No newline at end of file diff --git a/Tests/base/NSKVOSupport/general.m b/Tests/base/NSKVOSupport/general.m index ab76cacfa..edc346ced 100644 --- a/Tests/base/NSKVOSupport/general.m +++ b/Tests/base/NSKVOSupport/general.m @@ -1,6 +1,7 @@ /** general.m + Copyright (C) 2024 Free Software Foundation, Inc. Written by: Hugo Melder @@ -45,22 +46,12 @@ This code is licensed under the MIT License (MIT). #import #import "Testing.h" -#if defined(__OBJC2__) +#define BOXF(V) [NSNumber numberWithFloat: (V)] +#define BOXI(V) [NSNumber numberWithInteger: (V)] +#define MPAIR(K,V)\ + [NSMutableDictionary dictionaryWithObjectsAndKeys: V, K, nil] -#define PASS_ANY_THROW(expr, msg) \ - do \ - { \ - BOOL threw = NO; \ - @try \ - { \ - expr; \ - } \ - @catch (NSException * exception) \ - { \ - threw = YES; \ - } \ - PASS(threw, msg); \ - } while (0) +#if defined(__OBJC2__) @interface TestKVOSelfObserver : NSObject { @@ -256,14 +247,14 @@ + (NSSet *)keyPathsForValuesAffectingKeyDerivedTwoTimes + (NSSet *)keyPathsForValuesAffectingDependsOnTwoKeys { - return [NSSet setWithArray:@[ @"boolTrigger1", @"boolTrigger2" ]]; + return [NSSet setWithArray: [NSArray arrayWithObjects: + @"boolTrigger1", @"boolTrigger2", nil] ]; } + (NSSet *)keyPathsForValuesAffectingDependsOnTwoSubKeys { - return [NSSet setWithArray:@[ - @"cascadableKey.boolTrigger1", @"cascadableKey.boolTrigger2" - ]]; + return [NSSet setWithArray: [NSArray arrayWithObjects: + @"cascadableKey.boolTrigger1", @"cascadableKey.boolTrigger2", nil] ]; } - (bool)dependsOnTwoKeys @@ -434,7 +425,7 @@ @implementation TestKVOObject2 PASS_EQUAL( [[[[observer changesForKeypath:@"manuallyNotifyingIntegerProperty"] anyObject] info] objectForKey:NSKeyValueChangeNewKey], - @(1), + BOXI(1), "The new value stored in the change notification should be a boxed 1."); PASS_RUNS([observed removeObserver:observer @@ -622,7 +613,7 @@ @implementation TestKVOObject2 PASS_EQUAL( [[[[observer changesForKeypath:@"basicPodProperty"] anyObject] info] objectForKey:NSKeyValueChangeNewKey], - @(10), + BOXI(10), "The new value stored in the change notification should be a boxed 10."); PASS_RUNS([observed removeObserver:observer forKeyPath:@"basicPodProperty"], @@ -717,7 +708,7 @@ @implementation TestKVOObject2 "An INITIAL notification for nonNotifyingObjectProperty should " "have fired."); - PASS_EQUAL(@(NSKeyValueChangeSetting), + PASS_EQUAL(BOXF(NSKeyValueChangeSetting), [[[[observer changesForKeypath:@"nonNotifyingObjectProperty"] anyObject] info] objectForKey:NSKeyValueChangeKindKey], "The change kind should be NSKeyValueChangeSetting."); @@ -743,7 +734,7 @@ @implementation TestKVOObject2 forKeyPath:@"ivarWithoutSetter" options:NSKeyValueObservingOptionNew context:NULL]; - [observed setValue:@(1024) forKey:@"ivarWithoutSetter"]; + [observed setValue:BOXI(1024) forKey:@"ivarWithoutSetter"]; PASS_EQUAL([[observer changesForKeypath:@"ivarWithoutSetter"] count], 1, "One change on ivarWithoutSetter should have fired (using " @@ -752,7 +743,7 @@ @implementation TestKVOObject2 PASS_EQUAL( [[[[observer changesForKeypath:@"ivarWithoutSetter"] anyObject] info] objectForKey:NSKeyValueChangeNewKey], - @(1024), + BOXI(1024), "The new value stored in the change notification should a boxed 1024."); PASS_RUNS([observed removeObserver:observer forKeyPath:@"ivarWithoutSetter"], @@ -871,7 +862,7 @@ @implementation TestKVOObject2 [[[[observer changesForKeypath:@"cascadableKey.derivedObjectProperty.length"] anyObject] info] objectForKey:NSKeyValueChangeNewKey], - @(11), + BOXI(11), "The new value stored in the change notification should a boxed 11."); PASS_RUNS([observed @@ -1140,7 +1131,7 @@ @implementation TestKVOObject2 changesForKeypath:@"cascadableKey.basicObjectProperty"] anyObject] info] objectForKey:NSKeyValueChangeNewKey], "The initial value of basicObjectProperty should be nil."); - PASS_EQUAL(@(0), + PASS_EQUAL(BOXI(0), [[[[observer changesForKeypath:@"cascadableKey.basicPodProperty"] anyObject] info] objectForKey:NSKeyValueChangeNewKey], "The initial value of basicPodProperty should be 0."); @@ -1397,11 +1388,12 @@ @implementation TestKVOObject2 TestKVOObject *observed = [[[TestKVOObject alloc] init] autorelease]; TestKVOObserver *observer = [[[TestKVOObserver alloc] init] autorelease]; - PASS_ANY_THROW( + PASS_EXCEPTION( [observed removeObserver:observer forKeyPath:@"basicObjectProperty" context:(void *) (1)], - "Removing an unregistered observer should throw an exception."); + (NSString*)nil, + "Removing an unregistered observer should throw an exception.") END_SET("RemoveUnregistered"); } @@ -1498,7 +1490,7 @@ @implementation TestKVOObject2 observed.cascadableKey = child; child.dictionaryProperty = - [NSMutableDictionary dictionaryWithDictionary:@{@"Key1" : @"Value1"}]; + [NSMutableDictionary dictionaryWithDictionary:MPAIR(@"Key1" , @"Value1")]; [observed addObserver:observer forKeyPath:@"derivedCascadableKey.dictionaryProperty.Key1" @@ -1507,7 +1499,7 @@ @implementation TestKVOObject2 observed.cascadableKey = child2; child2.dictionaryProperty = - [NSMutableDictionary dictionaryWithDictionary:@{@"Key1" : @"Value2"}]; + [NSMutableDictionary dictionaryWithDictionary:MPAIR(@"Key1" , @"Value2")]; PASS_EQUAL(2, [observer numberOfObservedChanges], "Two changes should have " @@ -1533,9 +1525,9 @@ @implementation TestKVOObject2 // key dependent on sub keypath is dependent upon // dictionaryProperty.subDictionary - NSMutableDictionary *mutableDictionary = [[@{ - @"subDictionary" : @{@"floatGuy" : @(1.234)} - } mutableCopy] autorelease]; + NSMutableDictionary *mutableDictionary = MPAIR( + @"subDictionary", MPAIR(@"floatGuy" , BOXF(1.234)) + ); observed.dictionaryProperty = mutableDictionary; [observed addObserver:observer @@ -1544,16 +1536,16 @@ @implementation TestKVOObject2 context:nil]; mutableDictionary[@"subDictionary"] = - @{@"floatGuy" : @(3.456)}; // 1 notification + MPAIR(@"floatGuy" , BOXF(3.456)); // 1 notification - NSMutableDictionary *mutableDictionary2 = [[@{ - @"subDictionary" : @{@"floatGuy" : @(5.678)} - } mutableCopy] autorelease]; + NSMutableDictionary *mutableDictionary2 = MPAIR( + @"subDictionary", MPAIR(@"floatGuy" , BOXF(5.678)) + ); observed.dictionaryProperty = mutableDictionary2; // 2nd notification mutableDictionary2[@"subDictionary"] = - @{@"floatGuy" : @(7.890)}; // 3rd notification + MPAIR(@"floatGuy" , BOXF(7.890)); // 3rd notification PASS_EQUAL(3, [observer numberOfObservedChanges], "Three changes should have " @@ -1640,8 +1632,6 @@ @implementation TestKVOObject2 NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; TestKVOObject *observed = [[[TestKVOObject alloc] init] autorelease]; - TestKVOObject *child = [[[TestKVOObject alloc] init] autorelease]; - TestKVOObject *child2 = [[[TestKVOObject alloc] init] autorelease]; TestKVOObserver *observer = [[[TestKVOObserver alloc] init] autorelease]; observed.basicObjectProperty = @"Hello"; @@ -1832,7 +1822,7 @@ @implementation TestKVOObject2 forKeyPath:@"basicObjectProperty" options:NSKeyValueObservingOptionNew context:NULL]; - [observed setValue:@(1024) forKey:@"basicObjectProperty"]; + [observed setValue:BOXI(1024) forKey:@"basicObjectProperty"]; PASS_EQUAL([[observer changesForKeypath:@"basicObjectProperty"] count], 1, "ONLY one change on basicObjectProperty should have fired " @@ -1841,7 +1831,7 @@ @implementation TestKVOObject2 PASS_EQUAL( [[[[observer changesForKeypath:@"basicObjectProperty"] anyObject] info] objectForKey:NSKeyValueChangeNewKey], - @(1024), + BOXI(1024), "The new value stored in the change notification should a boxed 1024."); PASS_RUNS([observed removeObserver:observer @@ -1914,4 +1904,4 @@ @implementation TestKVOObject2 return 0; } -#endif \ No newline at end of file +#endif diff --git a/Tests/base/NSKVOSupport/kvoToMany.m b/Tests/base/NSKVOSupport/kvoToMany.m index 5f7985121..b612d1dbc 100644 --- a/Tests/base/NSKVOSupport/kvoToMany.m +++ b/Tests/base/NSKVOSupport/kvoToMany.m @@ -45,22 +45,10 @@ This code is licensed under the MIT License (MIT). #import #import "Testing.h" -#if defined(__OBJC2__) +#define BOXF(V) [NSNumber numberWithFloat: (V)] +#define BOXI(V) [NSNumber numberWithInteger: (V)] -#define PASS_ANY_THROW(expr, msg) \ - do \ - { \ - BOOL threw = NO; \ - @try \ - { \ - expr; \ - } \ - @catch (NSException * exception) \ - { \ - threw = YES; \ - } \ - PASS(threw, msg); \ - } while (0) +#if defined(__OBJC2__) @interface Observee : NSObject { @@ -464,12 +452,11 @@ - (void)dealloc performingBlock:^(Observee *observee) { [observee addObjectToBareArray:@"hello"]; } - andExpectChangeCallbacks:@[ + andExpectChangeCallbacks: [NSArray arrayWithObjects: ^(NSString *keyPath, id object, NSDictionary *change, void *context) { // Any notification here is illegal. PASS(NO, "Any notification here is illegal."); - } - ]]; + }, nil]]; PASS([facade hits] == 0, "No notifications were sent"); [facade release]; @@ -494,7 +481,7 @@ - (void)dealloc { NSIndexSet *indexes; - PASS_EQUAL(@(NSKeyValueChangeInsertion), change[NSKeyValueChangeKindKey], + PASS_EQUAL(BOXI(NSKeyValueChangeInsertion), change[NSKeyValueChangeKindKey], "firstInsertCallback: Change is an insertion"); indexes = change[NSKeyValueChangeIndexesKey]; @@ -514,7 +501,7 @@ - (void)dealloc NSIndexSet *indexes; // We should get an add on index 1 of "object2" - PASS_EQUAL(@(NSKeyValueChangeInsertion), change[NSKeyValueChangeKindKey], + PASS_EQUAL(BOXI(NSKeyValueChangeInsertion), change[NSKeyValueChangeKindKey], "secondInsertCallback: Change is an insertion"); indexes = change[NSKeyValueChangeIndexesKey]; @@ -533,7 +520,7 @@ - (void)dealloc { NSIndexSet *indexes; - PASS_EQUAL(@(NSKeyValueChangeRemoval), change[NSKeyValueChangeKindKey], + PASS_EQUAL(BOXI(NSKeyValueChangeRemoval), change[NSKeyValueChangeKindKey], "removalCallback: Change is a removal"); indexes = change[NSKeyValueChangeIndexesKey]; @@ -568,10 +555,9 @@ - (void)dealloc [observee addObjectToManualArray:@"object2"]; [observee removeObjectFromManualArrayIndex:0]; } - andExpectChangeCallbacks:@[ + andExpectChangeCallbacks: [NSArray arrayWithObjects: firstInsertCallback, secondInsertCallback, removalCallback, - illegalChangeNotification - ]]; + illegalChangeNotification, nil]]; PASS([facade hits] == 3, "Three notifications were sent"); [facade release]; @@ -590,23 +576,23 @@ - (void)dealloc [observee addObjectToManualArray:@"object2"]; [observee removeObjectFromManualArrayIndex:0]; } - andExpectChangeCallbacks:@[ + andExpectChangeCallbacks: [NSArray arrayWithObjects: firstInsertCallback, firstInsertCallback, secondInsertCallback, secondInsertCallback, removalCallback, removalCallback, - illegalChangeNotification - ]]; + illegalChangeNotification, nil]]; PASS([facade hits] == 6, "Six notifications were sent"); - PASS_EQUAL(@[ @"object2" ], [observee manualNotificationArray], - "Final array is 'object2'"); + PASS_EQUAL(([NSArray arrayWithObjects: @"object2", nil]), + [observee manualNotificationArray], + "Final array is 'object2'"); // This test expects one change notification: the initial one. Any more than // that is a failure. ChangeCallback initialNotificationCallback = CHANGE_CB { - NSArray *expectedArray = @[ @"object2" ]; + NSArray *expectedArray = [NSArray arrayWithObjects: @"object2", nil]; PASS_EQUAL(expectedArray, change[NSKeyValueChangeNewKey], - "Initial notification: New array is 'object2'"); + "Initial notification: New array is 'object2'"); NSLog(@"Initial notification: New array is %@", change[NSKeyValueChangeNewKey]); }; @@ -616,8 +602,8 @@ - (void)dealloc | NSKeyValueObservingOptionNew performingBlock:^(Observee *observee) { } - andExpectChangeCallbacks:@[ - initialNotificationCallback, illegalChangeNotification + andExpectChangeCallbacks: [NSArray arrayWithObjects: + initialNotificationCallback, illegalChangeNotification, nil ]]; PASS([facade hits] == 1, "One notification was sent"); @@ -634,10 +620,9 @@ - (void)dealloc [mediatedVersionOfArray addObject:@"object2"]; [mediatedVersionOfArray removeObjectAtIndex:0]; } - andExpectChangeCallbacks:@[ + andExpectChangeCallbacks: [NSArray arrayWithObjects: firstInsertCallback, secondInsertCallback, removalCallback, - illegalChangeNotification - ]]; + illegalChangeNotification, nil]]; PASS([facade hits] == 3, "Three notifications were sent"); [facade release]; @@ -658,10 +643,9 @@ - (void)dealloc [mediatedVersionOfArray addObject:@"object2"]; [mediatedVersionOfArray removeObjectAtIndex:0]; } - andExpectChangeCallbacks:@[ + andExpectChangeCallbacks: [NSArray arrayWithObjects: firstInsertCallback, secondInsertCallback, removalCallback, - illegalChangeNotification - ]]; + illegalChangeNotification, nil]]; PASS([facade hits] == 3, "Three notifications were sent"); [facade release]; @@ -681,10 +665,9 @@ - (void)dealloc [observee insertObject:@"object2" inArrayWithHelpersAtIndex:1]; [observee removeObjectFromArrayWithHelpersAtIndex:0]; } - andExpectChangeCallbacks:@[ + andExpectChangeCallbacks: [NSArray arrayWithObjects: firstInsertCallback, secondInsertCallback, removalCallback, - illegalChangeNotification - ]]; + illegalChangeNotification, nil]]; PASS([facade hits] == 3, "Three notifications were sent"); [facade release]; @@ -704,10 +687,10 @@ - (void)dealloc insertCallbackPost = CHANGE_CB { PASS(change[NSKeyValueChangeNotificationIsPriorKey] == nil, "Post change"); - PASS_EQUAL(@(NSKeyValueChangeSetting), change[NSKeyValueChangeKindKey], + PASS_EQUAL(BOXI(NSKeyValueChangeSetting), change[NSKeyValueChangeKindKey], "Change is a setting"); - PASS_EQUAL(@(0), change[NSKeyValueChangeOldKey], "Old value is 0"); - PASS_EQUAL(@(1), change[NSKeyValueChangeNewKey], "New value is 1"); + PASS_EQUAL(BOXI(0), change[NSKeyValueChangeOldKey], "Old value is 0"); + PASS_EQUAL(BOXI(1), change[NSKeyValueChangeNewKey], "New value is 1"); NSIndexSet *indexes = change[NSKeyValueChangeIndexesKey]; PASS(indexes == nil, "Indexes are nil"); @@ -730,9 +713,8 @@ - (void)dealloc [observee mutableArrayValueForKey:@"arrayWithHelpers"]; [mediatedVersionOfArray addObject:@"object1"]; } - andExpectChangeCallbacks:@[ - insertCallbackPost, illegalChangeNotification - ]]; + andExpectChangeCallbacks: [NSArray arrayWithObjects: + insertCallbackPost, illegalChangeNotification, nil]]; PASS([facade hits] == 1, "One notification was sent"); [facade release]; @@ -750,9 +732,8 @@ - (void)dealloc // dispatch one notification per change. [observee insertObject:@"object1" inArrayWithHelpersAtIndex:0]; } - andExpectChangeCallbacks:@[ - insertCallbackPost, illegalChangeNotification - ]]; + andExpectChangeCallbacks: [NSArray arrayWithObjects: + insertCallbackPost, illegalChangeNotification, nil]]; PASS([facade hits] == 1, "One notification was sent"); [facade release]; @@ -772,12 +753,12 @@ - (void)dealloc insertCallbackPost = CHANGE_CB { PASS(change[NSKeyValueChangeNotificationIsPriorKey] == nil, "Post change"); - PASS_EQUAL(@(NSKeyValueChangeSetting), change[NSKeyValueChangeKindKey], + PASS_EQUAL(BOXI(NSKeyValueChangeSetting), change[NSKeyValueChangeKindKey], "Change is a setting"); - NSArray *expectedOld = @[ @"Value" ]; + NSArray *expectedOld = [NSArray arrayWithObjects: @"Value", nil]; PASS_EQUAL(expectedOld, change[NSKeyValueChangeOldKey], "Old value is correct"); - NSArray *expectedNew = @[ @"Value", @"Value" ]; + NSArray *expectedNew = [NSArray arrayWithObjects: @"Value", @"Value", nil]; PASS_EQUAL(expectedNew, change[NSKeyValueChangeNewKey], "New value is correct"); NSIndexSet *indexes = change[NSKeyValueChangeIndexesKey]; @@ -802,9 +783,8 @@ - (void)dealloc [observee insertObject:[DummyObject makeDummy] inArrayWithHelpersAtIndex:0]; } - andExpectChangeCallbacks:@[ - insertCallbackPost, illegalChangeNotification - ]]; + andExpectChangeCallbacks: [NSArray arrayWithObjects: + insertCallbackPost, illegalChangeNotification, nil]]; PASS([facade hits] == 1, "One notification was sent"); [facade release]; @@ -846,7 +826,7 @@ - (void)dealloc performingBlock:^(Observee *observee) { [observee addObjectToManualArray:@"object1"]; } - andExpectChangeCallbacks:@[ onlyNewCallback, illegalChangeNotification ]]; + andExpectChangeCallbacks: [NSArray arrayWithObjects: onlyNewCallback, illegalChangeNotification, nil]]; [observee removeObserver:firstFacade.observer forKeyPath:@"manualNotificationArray"]; @@ -865,19 +845,22 @@ - (void)dealloc { START_SET("NSArrayShouldNotBeObservable"); - NSArray *test = @[ @1, @2, @3 ]; + NSArray *test = [NSArray arrayWithObjects: BOXI(1), BOXI(2), BOXI(3), nil]; TestObserver *observer = [TestObserver new]; - PASS_ANY_THROW([test addObserver:observer + PASS_EXCEPTION([test addObserver:observer forKeyPath:@"count" options:0 context:nil], - "NSArray is not observable"); + (NSString*)nil, + "NSArray is not observable"); // These would throw anyways because there should be no observer for the key // path, but test anyways - PASS_ANY_THROW([test removeObserver:observer forKeyPath:@"count"], - "Check removing non-existent observer"); - PASS_ANY_THROW([test removeObserver:observer forKeyPath:@"count" context:nil], + PASS_EXCEPTION([test removeObserver:observer forKeyPath:@"count"], + (NSString*)nil, + "Check removing non-existent observer"); + PASS_EXCEPTION([test removeObserver:observer forKeyPath:@"count" context:nil], + (NSString*)nil, "Check removing non-existent observer"); [observer release]; @@ -890,14 +873,15 @@ - (void)dealloc { START_SET("NSArrayShouldThrowWhenTryingToObserveIndexesOutOfRange"); - NSArray *test = @[ [Observee new], [Observee new] ]; + NSArray *test = [NSArray arrayWithObjects: [Observee new], [Observee new], nil]; TestObserver *observer = [TestObserver new]; - PASS_ANY_THROW([test addObserver:observer + PASS_EXCEPTION([test addObserver:observer toObjectsAtIndexes:[NSIndexSet indexSetWithIndex:4] forKeyPath:@"bareArray" options:0 context:nil], - "Observe index out of range"); + (NSString*)nil, + "Observe index out of range"); [observer release]; @@ -913,7 +897,7 @@ - (void)dealloc Observee *observee2 = [Observee new]; Observee *observee3 = [Observee new]; - NSArray *observeeArray = @[ observee1, observee2, observee3 ]; + NSArray *observeeArray = [NSArray arrayWithObjects: observee1, observee2, observee3, nil]; TestObserver *observer = [TestObserver new]; PASS_RUNS([observeeArray addObserver:observer @@ -979,20 +963,23 @@ - (void)dealloc { START_SET("NSSetShouldNotBeObservable"); - NSSet *test = [NSSet setWithObjects:@1, @2, @3, nil]; + NSSet *test = [NSSet setWithObjects:BOXI(1), BOXI(2), BOXI(3), nil]; TestObserver *observer = [TestObserver new]; - PASS_ANY_THROW([test addObserver:observer + PASS_EXCEPTION([test addObserver:observer forKeyPath:@"count" options:0 context:nil], - "NSSet is not observable"); + (NSString*)nil, + "NSSet is not observable"); // These would throw anyways because there should be no observer for the key // path, but test anyways - PASS_ANY_THROW([test removeObserver:observer forKeyPath:@"count"], - "Check removing non-existent observer"); - PASS_ANY_THROW([test removeObserver:observer forKeyPath:@"count" context:nil], - "Check removing non-existent observer"); + PASS_EXCEPTION([test removeObserver:observer forKeyPath:@"count"], + (NSString*)nil, + "Check removing non-existent observer"); + PASS_EXCEPTION([test removeObserver:observer forKeyPath:@"count" context:nil], + (NSString*)nil, + "Check removing non-existent observer"); [observer release]; @@ -1006,80 +993,80 @@ - (void)dealloc __block BOOL setSetChanged = NO; - // Union with @({@1, @2, @3}) to get @({@1, @2, @3}) + // Union with @({@(1), @(2), @(3)}) to get @({@(1), @(2), @(3)}) ChangeCallback unionCallback = CHANGE_CB { - PASS_EQUAL(@(NSKeyValueChangeInsertion), change[NSKeyValueChangeKindKey], + PASS_EQUAL(BOXI(NSKeyValueChangeInsertion), change[NSKeyValueChangeKindKey], "Union change is an insertion"); - NSSet *expected = [NSSet setWithObjects:@1, @2, @3, nil]; + NSSet *expected = [NSSet setWithObjects:BOXI(1), BOXI(2), BOXI(3), nil]; PASS_EQUAL(change[NSKeyValueChangeNewKey], expected, "Union new key is correct"); PASS(change[NSKeyValueChangeOldKey] == nil, "Union old key is nil"); }; - // Minus with @({@1}) to get @({@2, @3}) + // Minus with @({@(1)}) to get @({@(2), @(3)}) ChangeCallback minusCallback = CHANGE_CB { - PASS_EQUAL(change[NSKeyValueChangeKindKey], @(NSKeyValueChangeRemoval), + PASS_EQUAL(change[NSKeyValueChangeKindKey], BOXI(NSKeyValueChangeRemoval), "Minus change is a removal"); - PASS_EQUAL(change[NSKeyValueChangeOldKey], [NSSet setWithObject:@1], + PASS_EQUAL(change[NSKeyValueChangeOldKey], [NSSet setWithObject:BOXI(1)], "Minus old key is correct"); PASS(change[NSKeyValueChangeNewKey] == nil, "Minus new key is nil"); }; - // Add @1 to @({@2, @3}) to get @({@1, @2, @3}) + // Add @(1) to @({@(2), @(3)}) to get @({@(1), @(2), @(3)}) ChangeCallback addCallback = CHANGE_CB { - PASS_EQUAL(@(NSKeyValueChangeInsertion), change[NSKeyValueChangeKindKey], + PASS_EQUAL(BOXI(NSKeyValueChangeInsertion), change[NSKeyValueChangeKindKey], "Add change is an insertion"); NSLog(@"Change %@", change); - PASS_EQUAL([NSSet setWithObject:@1], change[NSKeyValueChangeNewKey], + PASS_EQUAL([NSSet setWithObject:BOXI(1)], change[NSKeyValueChangeNewKey], "Add new key is correct"); PASS(change[NSKeyValueChangeOldKey] == nil, "Add old key is nil"); }; - // Remove @1 from @({@1, @2, @3}) to get @({@2, @3}) + // Remove @(1) from @({@(1), @(2), @(3)}) to get @({@(2), @(3)}) ChangeCallback removeCallback = CHANGE_CB { - PASS_EQUAL(@(NSKeyValueChangeRemoval), change[NSKeyValueChangeKindKey], + PASS_EQUAL(BOXI(NSKeyValueChangeRemoval), change[NSKeyValueChangeKindKey], "Remove change is a removal"); - PASS_EQUAL([NSSet setWithObject:@1], change[NSKeyValueChangeOldKey], + PASS_EQUAL([NSSet setWithObject:BOXI(1)], change[NSKeyValueChangeOldKey], "Remove old key is correct"); PASS(change[NSKeyValueChangeNewKey] == nil, "Remove new key is nil"); }; - // Intersect with @({@2}) to get @({2}) + // Intersect with @({@(2)}) to get @({2}) ChangeCallback intersectCallback = CHANGE_CB { - PASS_EQUAL(@(NSKeyValueChangeRemoval), change[NSKeyValueChangeKindKey], + PASS_EQUAL(BOXI(NSKeyValueChangeRemoval), change[NSKeyValueChangeKindKey], "Intersect change is a removal"); - NSSet *expected = [NSSet setWithObject:@3]; + NSSet *expected = [NSSet setWithObject:BOXI(3)]; PASS_EQUAL(expected, change[NSKeyValueChangeOldKey], "Intersect old key is correct"); PASS(change[NSKeyValueChangeNewKey] == nil, "Intersect new key is nil"); }; - // Set with @({@3}) to get @({@3}) + // Set with @({@(3)}) to get @({@(3)}) ChangeCallback setCallback = CHANGE_CB { if (setSetChanged) { - PASS_EQUAL(@(NSKeyValueChangeReplacement), + PASS_EQUAL(BOXI(NSKeyValueChangeReplacement), change[NSKeyValueChangeKindKey], "Set change is a replacement"); - PASS_EQUAL([NSSet setWithObject:@2], change[NSKeyValueChangeOldKey], + PASS_EQUAL([NSSet setWithObject:BOXI(2)], change[NSKeyValueChangeOldKey], "Set old key is correct"); - PASS_EQUAL([NSSet setWithObject:@3], change[NSKeyValueChangeNewKey], + PASS_EQUAL([NSSet setWithObject:BOXI(3)], change[NSKeyValueChangeNewKey], "Set new key is correct"); } // setXxx method is not automatically swizzled for observation else { - PASS_EQUAL(@(NSKeyValueChangeSetting), change[NSKeyValueChangeKindKey], + PASS_EQUAL(BOXI(NSKeyValueChangeSetting), change[NSKeyValueChangeKindKey], "Set change is a setting"); - PASS_EQUAL([NSSet setWithObject:@3], change[NSKeyValueChangeOldKey], + PASS_EQUAL([NSSet setWithObject:BOXI(3)], change[NSKeyValueChangeOldKey], "Set old key is correct"); - PASS_EQUAL([NSSet setWithObject:@3], change[NSKeyValueChangeNewKey], + PASS_EQUAL([NSSet setWithObject:BOXI(3)], change[NSKeyValueChangeNewKey], "Set new key is correct"); } }; @@ -1099,16 +1086,16 @@ - (void)dealloc // This set is assisted by setter functions, and should also // dispatch one notification per change. [observee - addSetWithHelpers:[NSSet setWithObjects:@1, @2, @3, nil]]; - [observee removeSetWithHelpers:[NSSet setWithObject:@1]]; - [observee addSetWithHelpersObject:@1]; - [observee removeSetWithHelpersObject:@1]; - [observee intersectSetWithHelpers:[NSSet setWithObject:@2]]; - [observee setSetWithHelpers:[NSSet setWithObject:@3]]; + addSetWithHelpers:[NSSet setWithObjects:BOXI(1), BOXI(2), BOXI(3), nil]]; + [observee removeSetWithHelpers:[NSSet setWithObject:BOXI(1)]]; + [observee addSetWithHelpersObject:BOXI(1)]; + [observee removeSetWithHelpersObject:BOXI(1)]; + [observee intersectSetWithHelpers:[NSSet setWithObject:BOXI(2)]]; + [observee setSetWithHelpers:[NSSet setWithObject:BOXI(3)]]; } - andExpectChangeCallbacks:@[ + andExpectChangeCallbacks: [NSArray arrayWithObjects: unionCallback, minusCallback, addCallback, removeCallback, - intersectCallback, setCallback, illegalChangeNotification + intersectCallback, setCallback, illegalChangeNotification, nil ]]; PASS([facade hits] == 6, "All six notifications were sent (setWithHelpers)"); @@ -1128,17 +1115,16 @@ - (void)dealloc // The proxy set is a NSKeyValueIvarMutableSet NSMutableSet *proxySet = [observee mutableSetValueForKey:@"kvcMediatedSet"]; - [proxySet unionSet:[NSSet setWithObjects:@1, @2, @3, nil]]; - [proxySet minusSet:[NSSet setWithObject:@1]]; - [proxySet addObject:@1]; - [proxySet removeObject:@1]; - [proxySet intersectSet:[NSSet setWithObject:@2]]; - [proxySet setSet:[NSSet setWithObject:@3]]; + [proxySet unionSet:[NSSet setWithObjects:BOXI(1), BOXI(2), BOXI(3), nil]]; + [proxySet minusSet:[NSSet setWithObject:BOXI(1)]]; + [proxySet addObject:BOXI(1)]; + [proxySet removeObject:BOXI(1)]; + [proxySet intersectSet:[NSSet setWithObject:BOXI(2)]]; + [proxySet setSet:[NSSet setWithObject:BOXI(3)]]; } - andExpectChangeCallbacks:@[ + andExpectChangeCallbacks: [NSArray arrayWithObjects: unionCallback, minusCallback, addCallback, removeCallback, - intersectCallback, setCallback, illegalChangeNotification - ]]; + intersectCallback, setCallback, illegalChangeNotification, nil]]; PASS([facade hits] == 6, "All six notifications were sent (kvcMediatedSet)"); [observee release]; @@ -1152,17 +1138,16 @@ - (void)dealloc | NSKeyValueObservingOptionOld performingBlock:^(Observee *observee) { // Manually should dispatch one notification per change - [observee manualUnionSet:[NSSet setWithObjects:@1, @2, @3, nil]]; - [observee manualMinusSet:[NSSet setWithObject:@1]]; - [observee manualSetAddObject:@1]; - [observee manualSetRemoveObject:@1]; - [observee manualIntersectSet:[NSSet setWithObject:@2]]; - [observee manualSetSet:[NSSet setWithObject:@3]]; + [observee manualUnionSet:[NSSet setWithObjects:BOXI(1), BOXI(2), BOXI(3), nil]]; + [observee manualMinusSet:[NSSet setWithObject:BOXI(1)]]; + [observee manualSetAddObject:BOXI(1)]; + [observee manualSetRemoveObject:BOXI(1)]; + [observee manualIntersectSet:[NSSet setWithObject:BOXI(2)]]; + [observee manualSetSet:[NSSet setWithObject:BOXI(3)]]; } - andExpectChangeCallbacks:@[ + andExpectChangeCallbacks: [NSArray arrayWithObjects: unionCallback, minusCallback, addCallback, removeCallback, - intersectCallback, setCallback, illegalChangeNotification - ]]; + intersectCallback, setCallback, illegalChangeNotification, nil]]; PASS([facade hits] == 6, "All six notifications were sent (manualNotificationSet)"); @@ -1176,17 +1161,16 @@ - (void)dealloc // The proxy set is a NSKeyValueIvarMutableSet NSMutableSet *proxySet = [observee mutableSetValueForKey:@"proxySet"]; - [proxySet unionSet:[NSSet setWithObjects:@1, @2, @3, nil]]; - [proxySet minusSet:[NSSet setWithObject:@1]]; - [proxySet addObject:@1]; - [proxySet removeObject:@1]; - [proxySet intersectSet:[NSSet setWithObject:@2]]; - [proxySet setSet:[NSSet setWithObject:@3]]; + [proxySet unionSet:[NSSet setWithObjects:BOXI(1), BOXI(2), BOXI(3), nil]]; + [proxySet minusSet:[NSSet setWithObject:BOXI(1)]]; + [proxySet addObject:BOXI(1)]; + [proxySet removeObject:BOXI(1)]; + [proxySet intersectSet:[NSSet setWithObject:BOXI(2)]]; + [proxySet setSet:[NSSet setWithObject:BOXI(3)]]; } - andExpectChangeCallbacks:@[ + andExpectChangeCallbacks: [NSArray arrayWithObjects: unionCallback, minusCallback, addCallback, removeCallback, - intersectCallback, setCallback, illegalChangeNotification - ]]; + intersectCallback, setCallback, illegalChangeNotification, nil]]; PASS([facade hits] == 6, "All six notifications were sent (proxySet)"); /* Indirect slow proxy via NSInvocation to test NSKeyValueSlowMutableSet */ @@ -1198,17 +1182,16 @@ - (void)dealloc performingBlock:^(Observee *observee) { NSMutableSet *proxySet = [observee mutableSetValueForKey:@"proxyRoSet"]; - [proxySet unionSet:[NSSet setWithObjects:@1, @2, @3, nil]]; - [proxySet minusSet:[NSSet setWithObject:@1]]; - [proxySet addObject:@1]; - [proxySet removeObject:@1]; - [proxySet intersectSet:[NSSet setWithObject:@2]]; - [proxySet setSet:[NSSet setWithObject:@3]]; + [proxySet unionSet:[NSSet setWithObjects:BOXI(1), BOXI(2), BOXI(3), nil]]; + [proxySet minusSet:[NSSet setWithObject:BOXI(1)]]; + [proxySet addObject:BOXI(1)]; + [proxySet removeObject:BOXI(1)]; + [proxySet intersectSet:[NSSet setWithObject:BOXI(2)]]; + [proxySet setSet:[NSSet setWithObject:BOXI(3)]]; } - andExpectChangeCallbacks:@[ + andExpectChangeCallbacks: [NSArray arrayWithObjects: unionCallback, minusCallback, addCallback, removeCallback, - intersectCallback, setCallback, illegalChangeNotification - ]]; + intersectCallback, setCallback, illegalChangeNotification, nil]]; PASS([facade hits] == 6, "All six notifications were sent (proxySet)"); [observee release]; @@ -1256,4 +1239,4 @@ - (void)dealloc return 0; } -#endif \ No newline at end of file +#endif diff --git a/Tests/base/NSKVOSupport/newoldvalues.m b/Tests/base/NSKVOSupport/newoldvalues.m index 7e9254556..d30b472c1 100644 --- a/Tests/base/NSKVOSupport/newoldvalues.m +++ b/Tests/base/NSKVOSupport/newoldvalues.m @@ -1,76 +1,156 @@ #import #import "ObjectTesting.h" -#if defined(__OBJC2__) - @class Bar; @interface Foo : NSObject -@property (assign) Bar *globalBar; -@property (assign) NSInteger a; -@property (readonly) NSInteger b; +{ + Bar *globalBar; + NSInteger a; +} @end @interface Bar : NSObject -@property (assign) NSInteger x; -@property (strong, nonatomic) Foo *firstFoo; -@property (strong, nonatomic) Foo *secondFoo; +{ + NSInteger x; + Foo *firstFoo; + Foo *secondFoo; +} +- (NSInteger) x; @end @implementation Foo -+ (NSSet *)keyPathsForValuesAffectingB ++ (NSSet *) keyPathsForValuesAffectingB { - return [NSSet setWithArray:@[ @"a", @"globalBar.x" ]]; + return [NSSet setWithArray: [NSArray arrayWithObjects: + @"a", @"globalBar.x", nil]]; } -- (NSInteger)b +- (NSInteger) a +{ + return a; +} +- (void) setA: (NSInteger)v +{ + a = v; +} +- (NSInteger) b +{ + return [self a] + [globalBar x]; +} +- (Bar*) globalBar +{ + return globalBar; +} +- (void) setGlobalBar: (Bar*)v { - return self.a + self.globalBar.x; + globalBar = v; } @end @implementation Bar +- (Foo*) firstFoo +{ + return firstFoo; +} +- (void) setFirstFoo: (Foo*)v +{ + firstFoo = v; +} +- (Foo*) secondFoo +{ + return secondFoo; +} +- (void) setSecondFoo: (Foo*)v +{ + secondFoo = v; +} +- (NSInteger) x +{ + return x; +} +- (void) setX: (NSInteger)v +{ + x = v; +} + - (id)init { self = [super init]; if (self) { - self.firstFoo = [Foo new]; - self.firstFoo.globalBar = self; - self.secondFoo = [Foo new]; - self.secondFoo.globalBar = self; + [self setFirstFoo: [Foo new]]; + [[self firstFoo] setGlobalBar: self]; + [self setSecondFoo: [Foo new]]; + [[self secondFoo] setGlobalBar: self]; } return self; } + @end @interface Observer : NSObject -@property (assign) Foo *object; -@property (assign) NSInteger expectedOldValue; -@property (assign) NSInteger expectedNewValue; -@property (assign) NSInteger receivedCalls; +{ + Foo *object; + NSInteger expectedOldValue; + NSInteger expectedNewValue; + NSInteger receivedCalls; +} @end @implementation Observer +- (NSInteger) expectedOldValue +{ + return expectedOldValue; +} +- (void) setExpectedOldValue: (NSInteger)v +{ + expectedOldValue = v; +} +- (NSInteger) expectedNewValue +{ + return expectedNewValue; +} +- (void) setExpectedNewValue: (NSInteger)v +{ + expectedNewValue = v; +} +- (Foo*) object +{ + return object; +} +- (void) setObject: (Foo*)v +{ + object = v; +} +- (NSInteger) receivedCalls +{ + return receivedCalls; +} +- (void) setReceivedCalls: (NSInteger)v +{ + receivedCalls = v; +} + - (id)init { self = [super init]; if (self) { - self.receivedCalls = 0; + [self setReceivedCalls: 0]; } return self; } static char observerContext; -- (void)startObserving:(Foo *)target +- (void) startObserving:(Foo *)target { - self.object = target; + [self setObject: target]; [target addObserver:self forKeyPath:@"b" @@ -79,21 +159,21 @@ - (void)startObserving:(Foo *)target } - (void)observeValueForKeyPath:(NSString *)keyPath - ofObject:(id)object - change:(NSDictionary *)change + ofObject:(id)o + change:(NSDictionary *)change context:(void *)context { PASS(context == &observerContext, "context is correct"); - PASS(object == self.object, "object is correct"); + PASS(o == [self object], "object is correct"); - id newValue = change[NSKeyValueChangeNewKey]; - id oldValue = change[NSKeyValueChangeOldKey]; + id newValue = [change objectForKey: NSKeyValueChangeNewKey]; + id oldValue = [change objectForKey: NSKeyValueChangeOldKey]; PASS([oldValue integerValue] == self.expectedOldValue, "new value in change dict"); PASS([newValue integerValue] == self.expectedNewValue, "old value in change dict"); - self.receivedCalls++; + [self setReceivedCalls: [self receivedCalls] + 1]; } @end @@ -104,45 +184,39 @@ - (void)observeValueForKeyPath:(NSString *)keyPath NSAutoreleasePool *arp = [NSAutoreleasePool new]; Bar *bar = [Bar new]; - bar.x = 0; - bar.firstFoo.a = 1; - bar.secondFoo.a = 2; + [bar setX: 0]; + [[bar firstFoo] setA: 1]; + [[bar secondFoo] setA: 2]; Observer *obs1 = [Observer new]; Observer *obs2 = [Observer new]; - [obs1 startObserving:bar.firstFoo]; - [obs2 startObserving:bar.secondFoo]; - - obs1.expectedOldValue = 1; - obs1.expectedNewValue = 2; - obs2.expectedOldValue = 2; - obs2.expectedNewValue = 3; - bar.x = 1; + [obs1 startObserving: [bar firstFoo]]; + [obs2 startObserving: [bar secondFoo]]; + + [obs1 setExpectedOldValue: 1]; + [obs1 setExpectedNewValue: 2]; + [obs2 setExpectedOldValue: 2]; + [obs2 setExpectedNewValue: 3]; + [bar setX: 1]; PASS(obs1.receivedCalls == 1, "num observe calls"); PASS(obs2.receivedCalls == 1, "num observe calls"); - obs1.expectedOldValue = 2; - obs1.expectedNewValue = 2; - obs2.expectedOldValue = 3; - obs2.expectedNewValue = 3; - bar.x = 1; - PASS(obs1.receivedCalls == 2, "num observe calls"); - PASS(obs2.receivedCalls == 2, "num observe calls"); + [obs1 setExpectedOldValue: 2]; + [obs1 setExpectedNewValue: 2]; + [obs2 setExpectedOldValue: 3]; + [obs2 setExpectedNewValue: 3]; + [bar setX: 1]; + PASS([obs1 receivedCalls] == 2, "num observe calls"); + PASS([obs2 receivedCalls] == 2, "num observe calls"); - obs1.expectedOldValue = 2; - obs1.expectedNewValue = 3; - bar.firstFoo.a = 2; - PASS(obs1.receivedCalls == 3, "num observe calls"); - PASS(obs2.receivedCalls == 2, "num observe calls"); + [obs1 setExpectedOldValue: 2]; + [obs1 setExpectedNewValue: 3]; + [[bar firstFoo] setA: 2]; + PASS([obs1 receivedCalls] == 3, "num observe calls"); + PASS([obs2 receivedCalls] == 2, "num observe calls"); DESTROY(arp); -} -#else -int -main(int argc, char *argv[]) -{ return 0; } -#endif \ No newline at end of file