Skip to content

Commit

Permalink
Fix some of the non-portable code
Browse files Browse the repository at this point in the history
  • Loading branch information
rfm authored and triplef committed Aug 12, 2024
1 parent 2e4558f commit b7f0b94
Show file tree
Hide file tree
Showing 4 changed files with 356 additions and 276 deletions.
99 changes: 66 additions & 33 deletions Tests/base/NSKVOSupport/basic.m
Original file line number Diff line number Diff line change
@@ -1,23 +1,44 @@
#import <Foundation/Foundation.h>
#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
Expand All @@ -27,7 +48,7 @@ - (id)init
self = [super init];
if (self)
{
self.receivedCalls = 0;
receivedCalls = 0;
}
return self;
}
Expand All @@ -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<NSString *, id> *)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
Expand All @@ -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
76 changes: 33 additions & 43 deletions Tests/base/NSKVOSupport/general.m
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
/**
general.m
Copyright (C) 2024 Free Software Foundation, Inc.
Written by: Hugo Melder <[email protected]>
Expand Down Expand Up @@ -45,22 +46,12 @@ This code is licensed under the MIT License (MIT).
#import <Foundation/Foundation.h>
#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
{
Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -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"],
Expand Down Expand Up @@ -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.");
Expand All @@ -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 "
Expand All @@ -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"],
Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -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.");
Expand Down Expand Up @@ -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");
}
Expand Down Expand Up @@ -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"
Expand All @@ -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 "
Expand All @@ -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
Expand All @@ -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 "
Expand Down Expand Up @@ -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";
Expand Down Expand Up @@ -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 "
Expand All @@ -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
Expand Down Expand Up @@ -1914,4 +1904,4 @@ @implementation TestKVOObject2
return 0;
}

#endif
#endif
Loading

0 comments on commit b7f0b94

Please sign in to comment.