forked from gnustep/libs-base
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Additional tests for NSValue and KVC.
* Tests/base/NSValue/size-point-encoding.m: Tests for assumptions that GNUstep's reimplementation of Core Animation APIs makes with regards to NSValue and KVC behavior. For instance, one assumption made is that CGSize will be stored correctly. Additionally, there is the assumption that it will not be incorrectly unpacked into a CGPoint. Using KVC to assign a struct NSValue should also trigger a KVO notification. These tests were added while investigating the symptoms caused by https://savannah.gnu.org/bugs/index.php?53994, also known as gnustep#25.
- Loading branch information
Showing
3 changed files
with
117 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Empty file.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,104 @@ | ||
#import "ObjectTesting.h" | ||
#import <Foundation/Foundation.h> | ||
|
||
/* This definition of CGSize/CGPoint matches what is | ||
done in opal. */ | ||
typedef NSSize NearlyCGSize; | ||
typedef NSPoint NearlyCGPoint; | ||
|
||
@interface Container : NSObject | ||
{ | ||
NearlyCGSize _sz; | ||
BOOL _wasObserved; | ||
} | ||
@property (assign) NearlyCGSize sz; | ||
@property (assign) BOOL wasObserved; | ||
@end | ||
@implementation Container | ||
@synthesize sz=_sz; | ||
@synthesize wasObserved=_wasObserved; | ||
|
||
- (void) observeValueForKeyPath: (NSString *)keyPath | ||
ofObject: (id)object | ||
change: (NSDictionary *)change | ||
context: (void *)context | ||
{ | ||
self->_wasObserved = YES; | ||
} | ||
@end | ||
|
||
int main(int argc,char **argv) | ||
{ | ||
NSAutoreleasePool *pool = [NSAutoreleasePool new]; | ||
volatile BOOL result = NO; | ||
|
||
NSPoint point = {.x = 16.0, .y = 32.0}; | ||
NSValue *pointV = [NSValue valueWithPoint: point]; | ||
|
||
// An NSPoint should be represented with exactly the same | ||
// objCType as its @encode. | ||
result = !strcmp(@encode(NSPoint), [pointV objCType]); | ||
PASS(result, "@encode(NSPoint) == [pointV objCType]"); | ||
|
||
// An NSPoint should, despite the same layout, not be | ||
// represented the same as an NSSize. | ||
result = strcmp(@encode(NSSize), [pointV objCType]); | ||
PASS(result, "@encode(NSSize) != [pointV objCType]"); | ||
|
||
NearlyCGSize sz = {.width = 16.0, .height = 32.0}; | ||
// This test documents the current behavior of the | ||
// compiler / ABI: a rename of an existing struct should | ||
// be the same as the original. | ||
result = !strcmp(@encode(NearlyCGSize), @encode(NSSize)); | ||
PASS(result, "@encode(NearlyCGSize) == @encode(NSSize)"); | ||
|
||
// This test validates that a renamed NSSize will be | ||
// correctly loaded as an NSSize. | ||
NSValue * sizeV = [NSValue valueWithBytes: &sz | ||
objCType: @encode(NearlyCGSize)]; | ||
result = !strcmp(@encode(NearlyCGSize), [sizeV objCType]); | ||
PASS(result, "@encode(NearlyCGSize) == [sizeV objCType]"); | ||
|
||
// When the setter is directly used to change a struct value, | ||
// value should be observed with KVO and applied. | ||
Container * c = [Container new]; | ||
result = ![c wasObserved]; | ||
PASS(result, "!_wasObserved"); | ||
|
||
[c addObserver: c | ||
forKeyPath: @"sz" | ||
options: NSKeyValueObservingOptionOld | ||
context: nil]; | ||
result = ![c wasObserved]; | ||
PASS(result, "!_wasObserved"); | ||
|
||
[c setSz: sz]; | ||
result = [c wasObserved]; | ||
PASS(result, "_wasObserved"); | ||
|
||
result = [c sz].width == sz.width && [c sz].height == sz.height; | ||
PASS(result, "[c sz] == sz"); | ||
|
||
[c release]; | ||
|
||
// Rebuild the object and check that using KVC to set a size | ||
// works, and that it triggers a KVO notification. Ensure that | ||
// the new value is set and correct. | ||
c = [Container new]; | ||
[c addObserver: c | ||
forKeyPath: @"sz" | ||
options: NSKeyValueObservingOptionOld | ||
context: nil]; | ||
|
||
[c setValue: sizeV | ||
forKey: @"sz"]; | ||
result = [c wasObserved]; | ||
PASS(result, "_wasObserved"); | ||
|
||
result = [c sz].width == sz.width && [c sz].height == sz.height; | ||
PASS(result, "[c sz] == sz"); | ||
|
||
|
||
[pool release]; | ||
return (0); | ||
} |