Skip to content

Commit

Permalink
Additional tests for NSValue and KVC.
Browse files Browse the repository at this point in the history
* 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
ivucica committed May 27, 2018
1 parent 4ebe918 commit 4771a84
Show file tree
Hide file tree
Showing 3 changed files with 117 additions and 0 deletions.
13 changes: 13 additions & 0 deletions ChangeLog
@@ -1,3 +1,16 @@
2018-05-27 Ivan Vucica <ivan@vucica.net>

* 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.

2018-05-27 Fred Kiefer <fredkiefer@gmx.de>

* Tests/base/NSProcessInfo/general.m: Mark test for -systemUptime
Expand Down
Empty file added Tests/base/NSValue/TestInfo
Empty file.
104 changes: 104 additions & 0 deletions Tests/base/NSValue/size-point-encoding.m
@@ -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);
}

0 comments on commit 4771a84

Please sign in to comment.