Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Browse files

Squashed 'External/RXAssertions/' content from commit 0a532a6

git-subtree-dir: External/RXAssertions
git-subtree-split: 0a532a680760c9bdf5955d8a97406853704dc46c
  • Loading branch information...
commit 6df998746f5d40c560143af7ec47aef428cf6845 0 parents
@robrix authored
6 .gitignore
@@ -0,0 +1,6 @@
+.DS_Store
+*.tmproj
+*.xcodeproj/*.pbxuser
+*.xcodeproj/*.mode*
+xcuserdata
+build
9 LICENSE
@@ -0,0 +1,9 @@
+Copyright (c) 2007-2009, Monochrome Industries
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
+
+Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
+Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
+Neither the name of Monochrome Industries nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission.
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
115 README.mdown
@@ -0,0 +1,115 @@
+#RXAssertions
+
+(Cleverly assertive macros for your testing enjoyment.)
+
+The key ideas here are simple:
+
+1. _Simple API._ Fewer assertion macros are better.
+2. _Simple asserting._ The macros should give you a smart enough error message that you don’t need to provide your own—but you can, optionally, if you want to.
+3. _Doesn’t replace `STAssert*`_. If you want or need to fall back on the SenTestingKit macros, you can.
+
+
+#Assertion Macros
+
+All of these log source for the condition/expression as appropriate. Anything else that gets logged is noted alongside.
+
+- **`RXAssert(condition[, message])`**
+
+ Asserts that `condition` is true. Failures look like this:
+
+ <condition> was unexpectedly false.
+
+ If you supply a message, it will be logged instead of the default message shown above.
+
+- **`RXAssertFalse(condition[, message])`**
+
+ Asserts that `condition` is false. Failures look like this:
+
+ <condition> was unexpectedly true.
+
+ If you supply a message, it will be logged instead of the default message shown above.
+
+- **`RXAssertEquals(actual, expected[, message])`**
+
+ Asserts that the actual value is equal to the expected value; if it’s not, it logs what it actually was.
+
+ This is valid for use with objects, scalars (including floats; see RXRound for more), structs, and really anything that you’ve registered a comparator for. See `RXAssertionHelper` for more info. Failures look like this:
+
+ <actual expression> has value <actual value>, not expected value <expected value>.
+
+ If you supply a message, it will be logged immediately after the default message shown above.
+
+- **`RXAssertNotEquals(actual, unexpected[, message])`**
+
+ Asserts that the actual value is not equal to the unexpected value; if it is, it logs what it unexpectedly was. Failures look like this:
+
+ <actual expression> has unexpected value <actual value>.
+
+ If you supply a message, it will be logged immediately after the default message shown above.
+
+- **`RXAssertNil(object[, message])`**
+
+ Asserts that the object is nil. If it isn’t, it logs what it actually was. Failures look like this:
+
+ <expression> was unexpectedly <expression value>, not nil.
+
+ If you supply a message, it will be logged instead of the default message shown above.
+
+- **`RXAssertNotNil(object[, message])`**
+
+ Asserts that the object is not nil.
+
+ <expression> was unexpectedly nil.
+
+ If you supply a message, it will be logged instead of the default message shown above.
+
+#Helper Macros
+
+These are helpful macros which are used by RXAssertions or which are intended for your use.
+
+- **`RXUnionCast(value, type)`**
+
+ Casts value to type using an on-the-fly union. This is safe for use with strict aliasing.
+
+- **`RXRound(value, place)`**
+
+ Rounds value to place, e.g. `RXRound(M_PI, 0.01)` will result in `3.14`. You can use this with `RXAssertEquals` to easily test against floating point fixtures without worrying about IEEE float precision problems:
+
+ RXAssertEquals(RXRound([thing returnPotentiallyImpreciseFloat], 0.01), 1.23);
+
+ However, see `+[RXAssertionHelper floatingPointComparisonAccuracy]` for an alternative.
+
+
+#`RXAssertionHelper`
+
+True to its name, `RXAssertionHelper` helps the assertion macros with some of their tasks, namely:
+
+- **Comparing values of arbitrary type.**
+
+ `+registerComparisonFunction:forObjCType:` and `+compareValue:withValue:ofObjCType:` are used to add new comparators.
+
+ RXAssertions ships with comparators for signed and unsigned integers of 8, 16, 32, and 64 bits of width; `float`s and `double`s; objects and classes; `NSPoint`s (and `CGPoint`s via the same function); and arbitrary pointers (and thus, unsupported types will be compared with pointer equality, which will presumably fail every time).
+
+ To add other comparators, simply write the comparison function (matching the `RXAssertionHelperComparisonFunction` typedef) and register it with `RXAssertionHelper` somewhere convenient before you call `RXAssertEquals` with values of this type, perhaps in your test suite’s `+initialize` method.
+
+ There is currently no support for comparing values of wildly different types! The expected value is assigned to a variable of the actual value’s type. If there is sufficient need for comparing `CGAffineTransform`s with tree frogs, this policy can be revised.
+
+- **Describing values of arbitrary type.**
+
+ `+registerDescriptionFunction:forObjCType` and `+descriptionForValue:ofObjCType:` are used to return an `NSString` instance describing the passed-in value.
+
+ These are widely used in the assertion macros for logging of actual and expected values. RXAssertions includes descriptors for signed and unsigned integers of 8, 16, 32, and 64 bits of width; `float`s and `double`s; objects and classes; `NSPoint`s (and `CGPoint`s via the same function); and arbitrary pointers (which includes pointers to any unsupported types—so if you see hex dumps of your compared values, you will want to add a descriptor).
+
+ Adding a descriptor is even simpler than adding a comparator; a `RXAssertionHelperDescriptionFunction` takes a reference to the value to be described, casts it (presumably using `RXUnionCast`) to the expected type, and builds an `NSString` from it.
+
+- **Controlling the accuracy at which `RXAssertEquals` compares `float` and `double` values.**
+
+ `+[RXAssertionHelper floatingPointComparisonAccuracy]` and `+[RXAssertionHelper setFloatingPointComparisonAccuracy:]` are used to get and set the floating point accuracy, by default 0, used by the comparators for `float` and `double` values, and thus by `RXAssertEquals`.
+
+ There is no support for managing separate `float` and `double` accuracies; if this would simplify things for you, it would be a simple change to make.
+
+
+#What’s Missing
+
+- Exception interaction of any kind. Continue using the `STAssert*` macros for exceptions until this is implemented.
+- Comparators and descriptors for `long double`, `CGSize`, `CGRect`, `CGAffineTransform`, `CFType` instances, and many other things. Patches welcome.
25 RXAssertionHelperTests.m
@@ -0,0 +1,25 @@
+// RXAssertionHelperTests.m
+// Created by Rob Rix on 2010-04-09
+// Copyright 2010 Monochrome Industries
+
+#import "RXAssertions.h"
+
+@interface RXAssertionHelperTests : SenTestCase
+@end
+
+@implementation RXAssertionHelperTests
+
+-(void)testCanTestRangesForEquality {
+ NSRange a = NSMakeRange(0, 1), b = NSMakeRange(0, 1), c = NSMakeRange(1, 2);
+ RXAssert([RXAssertionHelper compareValue: &a withValue: &b ofObjCType: @encode(NSRange)]);
+ RXAssertFalse([RXAssertionHelper compareValue: &a withValue: &c ofObjCType: @encode(NSRange)]);
+
+ // RXAssertEquals(NSMakeRange(0, 1), NSMakeRange(0, 1));
+ // RXAssertNotEquals(NSMakeRange(0, 1), NSMakeRange(1, 2));
+}
+
+-(void)testCanTestCoreFoundationStringsForEquality {
+ RXAssertEquals(CFSTR("foo"), (CFStringRef)@"foo");
+}
+
+@end
82 RXAssertions.h
@@ -0,0 +1,82 @@
+// RXAssertions.h
+// Created by Rob Rix on 2009-08-20
+// Copyright 2009 Decimus Software, Inc.
+
+#import <SenTestingKit/SenTestingKit.h>
+
+// Assertion macros that don’t require you to describe the assertion. Perfect for use with intention-revealing code.
+
+// Don’t use this unless you’re writing your own assertions. The first argument is ignored, so the assertions can have optional messages appended to them without suffering a compiler error.
+#define RXOptionalMessageString(ignored, format, ...) [NSString stringWithFormat: (format), ## __VA_ARGS__]
+
+#define RXAssert(_expression, ...) do {\
+ __typeof__(_expression) __condition = (_expression);\
+ if(!__condition)\
+ STFail(RXOptionalMessageString(, ## __VA_ARGS__, @"%s was unexpectedly false.", #_expression));\
+} while(0)
+#define RXAssertFalse(_expression, ...) do {\
+ __typeof__(_expression) __condition = (_expression);\
+ if(__condition)\
+ STFail(RXOptionalMessageString(, ## __VA_ARGS__, @"%s was unexpectedly true.", #_expression));\
+} while(0)
+
+// casts the expected value to the type of the actual value. will fail (and rightly so) if you try crazy casts like struct to pointer.
+#define RXAssertEquals(_actual, _expected, ...) do {\
+ __typeof__(_actual) __actual = (_actual), __expected = (__typeof__(__actual))(_expected);\
+ if(![RXAssertionHelper compareValue: &__actual withValue: &__expected ofObjCType: @encode(__typeof__(__actual))]) {\
+ STFail(@"%s has value %@, not expected value %@. %@", #_actual, [RXAssertionHelper descriptionForValue: &__actual ofObjCType: @encode(__typeof__(__actual))], [RXAssertionHelper descriptionForValue: &__expected ofObjCType: @encode(__typeof__(__actual))], RXOptionalMessageString(, ## __VA_ARGS__, @""));\
+ }\
+} while(0)
+#define RXAssertNotEquals(_actual, _expected, ...) do {\
+ __typeof__(_actual) __actual = (_actual), __expected = (__typeof__(__actual))(_expected);\
+ if([RXAssertionHelper compareValue: &__actual withValue: &__expected ofObjCType: @encode(__typeof__(__actual))]) {\
+ STFail(@"%s has unexpected value %@. %@", #_actual, [RXAssertionHelper descriptionForValue: &__actual ofObjCType: @encode(__typeof__(__actual))], RXOptionalMessageString(, ## __VA_ARGS__, @""));\
+ }\
+} while(0)
+
+#define RXAssertNil(_thing, ...) do {\
+ __typeof__(_thing) __thing = (_thing);\
+ if(__thing != nil) STFail(RXOptionalMessageString(, ## __VA_ARGS__, @"%s was unexpectedly %@, not nil.", #_thing, __thing));\
+} while(0)
+#define RXAssertNotNil(_thing, ...) do {\
+ if((_thing) == nil) STFail(RXOptionalMessageString(, ## __VA_ARGS__, @"%s was unexpectedly nil.", #_thing));\
+} while(0)
+
+
+//#ifdef __clang__
+#if 0
+ // this is bad, as strict aliasing will break it, but clang doesn’t handle union casts correctly
+ #define RXCast(x, toType) *(toType *)&(x)
+#else
+ #define RXCast(x, toType) (((union{__typeof__(x) a; toType b;})x).b)
+#endif
+#define RXRound(value, place) (round((value) / (place)) * (place))
+
+
+typedef BOOL (*RXAssertionHelperComparisonFunction)(const void *aRef, const void *bRef);
+typedef NSString *(*RXAssertionHelperDescriptionFunction)(const void *ref);
+
+
+// making these functions available for registering Polymorph types
+BOOL RXAssertionHelperObjectComparison(const void *a, const void *b);
+NSString *RXAssertionHelperObjectDescription(const void *ref);
+
+BOOL RXAssertionHelperCFTypeRefComparison(const void *a, const void *b);
+NSString *RXAssertionHelperCFTypeRefDescription(const void *ref);
+
+
+@interface RXAssertionHelper : NSObject
+
++(void)registerComparisonFunction:(RXAssertionHelperComparisonFunction)comparator forObjCType:(const char *)type;
++(BOOL)compareValue:(const void *)aRef withValue:(const void *)bRef ofObjCType:(const char *)type;
+
++(void)registerDescriptionFunction:(RXAssertionHelperDescriptionFunction)descriptor forObjCType:(const char *)type;
++(NSString *)descriptionForValue:(const void *)ref ofObjCType:(const char *)type;
+
++(double)floatingPointComparisonAccuracy;
++(void)setFloatingPointComparisonAccuracy:(double)epsilon;
+
+// returns a nicely formatted name for the test case selector
++(NSString *)humanReadableNameForTestCaseSelector:(SEL)selector;
+
+@end
266 RXAssertions.m
@@ -0,0 +1,266 @@
+// RXAssertions.m
+// Created by Rob Rix on 2009-08-20
+// Copyright 2009 Decimus Software, Inc.
+
+#import <math.h>
+#import "RXAssertions.h"
+
+static NSMutableDictionary *RXAssertionHelperComparisonFunctions = nil;
+static NSMutableDictionary *RXAssertionHelperDescriptionFunctions = nil;
+
+static double RXAssertionHelperFloatingPointComparisonAccuracy = 0.0;
+
+BOOL RXAssertionHelperInt8Comparison(const void *a, const void *b) {
+ return (*(RXCast(a, const uint8_t *))) == (*(RXCast(b, const uint8_t *)));
+}
+
+BOOL RXAssertionHelperInt16Comparison(const void *a, const void *b) {
+ return (*(RXCast(a, const uint16_t *))) == (*(RXCast(b, const uint16_t *)));
+}
+
+BOOL RXAssertionHelperInt32Comparison(const void *a, const void *b) {
+ return (*(RXCast(a, const uint32_t *))) == (*(RXCast(b, const uint32_t *)));
+}
+
+BOOL RXAssertionHelperInt64Comparison(const void *a, const void *b) {
+ return (*(RXCast(a, const uint64_t *))) == (*(RXCast(b, const uint64_t *)));
+}
+
+BOOL RXAssertionHelperFloatComparison(const void *a, const void *b) {
+ double _a = *RXCast(a, const float *), _b = *RXCast(b, const float *);
+ return islessequal(MAX(_a, _b) - MIN(_a, _b), RXAssertionHelperFloatingPointComparisonAccuracy);
+}
+
+BOOL RXAssertionHelperDoubleComparison(const void *a, const void *b) {
+ double _a = *RXCast(a, const double *), _b = *RXCast(b, const double *);
+ return islessequal(MAX(_a, _b) - MIN(_a, _b), RXAssertionHelperFloatingPointComparisonAccuracy);
+}
+
+BOOL RXAssertionHelperObjectComparison(const void *a, const void *b) {
+ const id _a = *RXCast(a, const id *), _b = *RXCast(b, const id *);
+ return (_a == _b) || [_a isEqual: _b];
+}
+
+BOOL RXAssertionHelperCFTypeRefComparison(const void *a, const void *b) {
+ CFTypeRef _a = *RXCast(a, CFTypeRef *), _b = *RXCast(b, CFTypeRef *);
+ return
+ (_a == _b)
+ || ((_a != nil) && (_b != nil) && CFEqual(_a, _b));
+}
+
+BOOL RXAssertionHelperNSPointComparison(const void *a, const void *b) {
+ return NSEqualPoints(*RXCast(a, const NSPoint *), *RXCast(b, const NSPoint *));
+}
+
+BOOL RXAssertionHelperNSRangeComparison(const void *a, const void *b) {
+ return NSEqualRanges(*RXCast(a, const NSRange *), *RXCast(b, const NSRange *));
+}
+
+
+NSString *RXAssertionHelperHexadecimalDescription(const void *ref) {
+ return [NSString stringWithFormat: @"%x", *RXCast(ref, const void **)];
+}
+
+NSString *RXAssertionHelperInt8Description(const void *ref) {
+ return [NSString stringWithFormat: @"%d", *RXCast(ref, const int8_t *)];
+}
+
+NSString *RXAssertionHelperUInt8Description(const void *ref) {
+ return [NSString stringWithFormat: @"%u", *RXCast(ref, const uint8_t *)];
+}
+
+NSString *RXAssertionHelperInt16Description(const void *ref) {
+ return [NSString stringWithFormat: @"%d", *RXCast(ref, const int16_t *)];
+}
+
+NSString *RXAssertionHelperUInt16Description(const void *ref) {
+ return [NSString stringWithFormat: @"%u", *RXCast(ref, const uint16_t *)];
+}
+
+NSString *RXAssertionHelperInt32Description(const void *ref) {
+ return [NSString stringWithFormat: @"%d", *RXCast(ref, const int32_t *)];
+}
+
+NSString *RXAssertionHelperUInt32Description(const void *ref) {
+ return [NSString stringWithFormat: @"%u", *RXCast(ref, const uint32_t *)];
+}
+
+NSString *RXAssertionHelperInt64Description(const void *ref) {
+ return [NSString stringWithFormat: @"%qi", *RXCast(ref, const int64_t *)];
+}
+
+NSString *RXAssertionHelperUInt64Description(const void *ref) {
+ return [NSString stringWithFormat: @"%qu", *RXCast(ref, const uint64_t *)];
+}
+
+NSString *RXAssertionHelperFloatDescription(const void *ref) {
+ return [NSString stringWithFormat: @"%f", *RXCast(ref, const float *)];
+}
+
+NSString *RXAssertionHelperDoubleDescription(const void *ref) {
+ return [NSString stringWithFormat: @"%f", *RXCast(ref, const double *)];
+}
+
+NSString *RXAssertionHelperObjectDescription(const void *ref) {
+ return [NSString stringWithFormat: @"%@", *RXCast(ref, const id *)];
+}
+
+//NSString *RXAssertionHelperCFTypeRefDescription(const void *ref) {
+// CFTypeRef _ref = *RXCast(ref, CFTypeRef *);
+// return _ref ? [(__bridge id)_ref description] : @"(null)";
+//}
+
+NSString *RXAssertionHelperNSPointDescription(const void *ref) {
+ return NSStringFromPoint(*RXCast(ref, const NSPoint *));
+}
+
+NSString *RXAssertionHelperNSRangeDescription(const void *ref) {
+ return NSStringFromRange(*RXCast(ref, const NSRange *));
+}
+
+
+@implementation RXAssertionHelper
+
++(void)initialize {
+ if(!RXAssertionHelperComparisonFunctions) {
+ RXAssertionHelperComparisonFunctions = [[NSMutableDictionary alloc] init];
+ }
+ if(!RXAssertionHelperDescriptionFunctions) {
+ RXAssertionHelperDescriptionFunctions = [[NSMutableDictionary alloc] init];
+ }
+
+#ifdef __LP64__
+ [self registerComparisonFunction: RXAssertionHelperInt64Comparison forObjCType: @encode(void *)];
+#else
+ [self registerComparisonFunction: RXAssertionHelperInt32Comparison forObjCType: @encode(void *)];
+#endif
+ [self registerComparisonFunction: RXAssertionHelperInt8Comparison forObjCType: @encode(int8_t)];
+ [self registerComparisonFunction: RXAssertionHelperInt8Comparison forObjCType: @encode(uint8_t)];
+ [self registerComparisonFunction: RXAssertionHelperInt16Comparison forObjCType: @encode(int16_t)];
+ [self registerComparisonFunction: RXAssertionHelperInt16Comparison forObjCType: @encode(uint16_t)];
+ [self registerComparisonFunction: RXAssertionHelperInt32Comparison forObjCType: @encode(int32_t)];
+ [self registerComparisonFunction: RXAssertionHelperInt32Comparison forObjCType: @encode(uint32_t)];
+ [self registerComparisonFunction: RXAssertionHelperInt64Comparison forObjCType: @encode(int64_t)];
+ [self registerComparisonFunction: RXAssertionHelperInt64Comparison forObjCType: @encode(uint64_t)];
+ [self registerComparisonFunction: RXAssertionHelperFloatComparison forObjCType: @encode(float)];
+ [self registerComparisonFunction: RXAssertionHelperDoubleComparison forObjCType: @encode(double)];
+ [self registerComparisonFunction: RXAssertionHelperObjectComparison forObjCType: @encode(id)];
+ [self registerComparisonFunction: RXAssertionHelperObjectComparison forObjCType: @encode(Class)];
+ CFStringRef string = NULL;
+ CFArrayRef array = NULL;
+ CFCharacterSetRef characterSet = NULL;
+ [self registerComparisonFunction: RXAssertionHelperCFTypeRefComparison forObjCType: @encode(__typeof__(string))]; // __typeof__ keeps qualifiers, e.g. const
+ [self registerComparisonFunction: RXAssertionHelperCFTypeRefComparison forObjCType: @encode(__typeof__(array))]; // __typeof__ keeps qualifiers, e.g. const
+ [self registerComparisonFunction: RXAssertionHelperCFTypeRefComparison forObjCType: @encode(__typeof__(characterSet))]; // __typeof__ keeps qualifiers, e.g. const
+ [self registerComparisonFunction: RXAssertionHelperNSPointComparison forObjCType: @encode(NSPoint)];
+ [self registerComparisonFunction: RXAssertionHelperNSPointComparison forObjCType: @encode(CGPoint)];
+ [self registerComparisonFunction: RXAssertionHelperNSRangeComparison forObjCType: @encode(NSRange)];
+
+ [self registerDescriptionFunction: RXAssertionHelperHexadecimalDescription forObjCType: @encode(void *)];
+ [self registerDescriptionFunction: RXAssertionHelperInt8Description forObjCType: @encode(int8_t)];
+ [self registerDescriptionFunction: RXAssertionHelperUInt8Description forObjCType: @encode(uint8_t)];
+ [self registerDescriptionFunction: RXAssertionHelperInt16Description forObjCType: @encode(int16_t)];
+ [self registerDescriptionFunction: RXAssertionHelperUInt16Description forObjCType: @encode(uint16_t)];
+ [self registerDescriptionFunction: RXAssertionHelperInt32Description forObjCType: @encode(int32_t)];
+ [self registerDescriptionFunction: RXAssertionHelperUInt32Description forObjCType: @encode(uint32_t)];
+ [self registerDescriptionFunction: RXAssertionHelperInt64Description forObjCType: @encode(int64_t)];
+ [self registerDescriptionFunction: RXAssertionHelperUInt64Description forObjCType: @encode(uint64_t)];
+ [self registerDescriptionFunction: RXAssertionHelperFloatDescription forObjCType: @encode(float)];
+ [self registerDescriptionFunction: RXAssertionHelperDoubleDescription forObjCType: @encode(double)];
+ [self registerDescriptionFunction: RXAssertionHelperObjectDescription forObjCType: @encode(id)];
+ [self registerDescriptionFunction: RXAssertionHelperObjectDescription forObjCType: @encode(Class)];
+// [self registerDescriptionFunction: RXAssertionHelperCFTypeRefDescription forObjCType: @encode(__typeof__(string))]; // __typeof__ keeps qualifiers, e.g. const
+// [self registerDescriptionFunction: RXAssertionHelperCFTypeRefDescription forObjCType: @encode(__typeof__(array))]; // __typeof__ keeps qualifiers, e.g. const
+// [self registerDescriptionFunction: RXAssertionHelperCFTypeRefDescription forObjCType: @encode(__typeof__(characterSet))]; // __typeof__ keeps qualifiers, e.g. const
+ [self registerDescriptionFunction: RXAssertionHelperNSPointDescription forObjCType: @encode(NSPoint)];
+ [self registerDescriptionFunction: RXAssertionHelperNSPointDescription forObjCType: @encode(CGPoint)];
+ [self registerDescriptionFunction: RXAssertionHelperNSRangeDescription forObjCType: @encode(NSRange)];
+}
+
+
++(NSString *)keyForObjCType:(const char *)type {
+ return [NSString stringWithFormat: @"%s", type];
+}
+
++(RXAssertionHelperComparisonFunction)comparisonFunctionForObjCType:(const char *)type {
+ return [[RXAssertionHelperComparisonFunctions objectForKey: [self keyForObjCType: type]] pointerValue];
+}
+
++(void)registerComparisonFunction:(RXAssertionHelperComparisonFunction)comparator forObjCType:(const char *)type {
+ [RXAssertionHelperComparisonFunctions setObject: [NSValue valueWithPointer: comparator] forKey: [self keyForObjCType: type]];
+}
+
++(BOOL)compareValue:(const void *)aRef withValue:(const void *)bRef ofObjCType:(const char *)type {
+ RXAssertionHelperComparisonFunction function =
+ [self comparisonFunctionForObjCType: type]
+ ?:
+#ifdef __LP64__
+ RXAssertionHelperInt64Comparison;
+#else
+ RXAssertionHelperInt32Comparison;
+#endif
+ return function(aRef, bRef);
+}
+
+
++(RXAssertionHelperDescriptionFunction)descriptionFunctionForObjCType:(const char *)type {
+ return [[RXAssertionHelperDescriptionFunctions objectForKey: [self keyForObjCType: type]] pointerValue];
+}
+
++(void)registerDescriptionFunction:(RXAssertionHelperDescriptionFunction)descriptor forObjCType:(const char *)type {
+ [RXAssertionHelperDescriptionFunctions setObject: [NSValue valueWithPointer: descriptor] forKey: [self keyForObjCType: type]];
+}
+
++(NSString *)descriptionForValue:(const void *)ref ofObjCType:(const char *)type {
+ RXAssertionHelperDescriptionFunction function = [self descriptionFunctionForObjCType: type] ?: RXAssertionHelperHexadecimalDescription;
+ return function(ref);
+}
+
+
++(double)floatingPointComparisonAccuracy {
+ return RXAssertionHelperFloatingPointComparisonAccuracy;
+}
+
++(void)setFloatingPointComparisonAccuracy:(double)epsilon {
+ RXAssertionHelperFloatingPointComparisonAccuracy = epsilon;
+}
+
+
++(NSString *)humanReadableNameForTestCaseSelector:(SEL)selector {
+ NSMutableArray *words = [NSMutableArray array];
+ NSScanner *scanner = [NSScanner scannerWithString: NSStringFromSelector(selector)];
+ [scanner scanString: @"test" intoString: nil]; // skip "test"
+ while(!scanner.isAtEnd) {
+ NSString *up = nil, *lo = nil;
+ NSUInteger cursor = scanner.scanLocation;
+ up = [scanner.string substringWithRange: NSMakeRange(cursor, 1)]; // grab the first character
+ scanner.scanLocation = cursor + 1;
+ [scanner scanCharactersFromSet: [NSCharacterSet lowercaseLetterCharacterSet] intoString: &lo];
+ [words addObject: [NSString stringWithFormat: @"%@%@", [up lowercaseString], lo ?: @""]];
+ }
+ return [words componentsJoinedByString: @" "];
+}
+
++(NSString *)humanReadableNameForTestSuiteClass:(Class)klass {
+ NSString *name = NSStringFromClass(klass);
+ NSString *result = name;
+ NSRange testsRange = [name rangeOfString: @"Tests" options: NSBackwardsSearch | NSAnchoredSearch];
+ NSRange testRange = [name rangeOfString: @"Test" options: NSBackwardsSearch | NSAnchoredSearch];
+ if(testsRange.location != NSNotFound) {
+ result = [name substringToIndex: testsRange.location];
+ } else if(testRange.location != NSNotFound) {
+ result = [name substringToIndex: testRange.location];
+ }
+ return result;
+}
+
+@end
+
+
+@implementation SenTestCase (RXAssertionsPrettierNamesForTestCases)
+
+//-(NSString *)name {
+// return [NSString stringWithFormat: @"%@ %@", [RXAssertionHelper humanReadableNameForTestSuiteClass: self.class], [RXAssertionHelper humanReadableNameForTestCaseSelector: self.invocation.selector]];
+//}
+
+@end
7 RXAssertions.pch
@@ -0,0 +1,7 @@
+// RXAssertions_Prefix.pch
+// Created by Rob Rix on 2009-09-17
+// Copyright 2009 Monochrome Industries
+
+#ifdef __OBJC__
+ #import <Foundation/Foundation.h>
+#endif
387 RXAssertions.xcodeproj/project.pbxproj
@@ -0,0 +1,387 @@
+// !$*UTF8*$!
+{
+ archiveVersion = 1;
+ classes = {
+ };
+ objectVersion = 45;
+ objects = {
+
+/* Begin PBXBuildFile section */
+ D415F64311A28E060027AAD8 /* RXAssertionsTests.m in Sources */ = {isa = PBXBuildFile; fileRef = D442A48D106FD99700944F07 /* RXAssertionsTests.m */; };
+ D442A493106FD9BF00944F07 /* libRXAssertions.a in Frameworks */ = {isa = PBXBuildFile; fileRef = D2AAC07E0554694100DB518D /* libRXAssertions.a */; };
+ D472095311581618003F9546 /* RXMockObjectTests.m in Sources */ = {isa = PBXBuildFile; fileRef = D472095211581618003F9546 /* RXMockObjectTests.m */; };
+ D4C03B4A1063445800925A75 /* RXAssertions.h in Headers */ = {isa = PBXBuildFile; fileRef = D4C03B471063445800925A75 /* RXAssertions.h */; };
+ D4C03B4B1063445800925A75 /* RXAssertions.m in Sources */ = {isa = PBXBuildFile; fileRef = D4C03B481063445800925A75 /* RXAssertions.m */; };
+ D4CE0C55116FB8E400FE6B86 /* RXAssertionHelperTests.m in Sources */ = {isa = PBXBuildFile; fileRef = D4CE0C54116FB8E400FE6B86 /* RXAssertionHelperTests.m */; };
+ D4F3DD2811558CC2008BB0F8 /* RXMockObject.h in Headers */ = {isa = PBXBuildFile; fileRef = D4F3DD2611558CC2008BB0F8 /* RXMockObject.h */; };
+ D4F3DD2911558CC2008BB0F8 /* RXMockObject.m in Sources */ = {isa = PBXBuildFile; fileRef = D4F3DD2711558CC2008BB0F8 /* RXMockObject.m */; };
+/* End PBXBuildFile section */
+
+/* Begin PBXContainerItemProxy section */
+ D442A48F106FD9A400944F07 /* PBXContainerItemProxy */ = {
+ isa = PBXContainerItemProxy;
+ containerPortal = 0867D690FE84028FC02AAC07 /* Project object */;
+ proxyType = 1;
+ remoteGlobalIDString = D2AAC07D0554694100DB518D;
+ remoteInfo = RXAssertions;
+ };
+/* End PBXContainerItemProxy section */
+
+/* Begin PBXFileReference section */
+ D2AAC07E0554694100DB518D /* libRXAssertions.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = libRXAssertions.a; sourceTree = BUILT_PRODUCTS_DIR; };
+ D442A488106FD94900944F07 /* Tests.octest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = Tests.octest; sourceTree = BUILT_PRODUCTS_DIR; };
+ D442A489106FD94900944F07 /* Tests-Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = "Tests-Info.plist"; sourceTree = "<group>"; };
+ D442A48D106FD99700944F07 /* RXAssertionsTests.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RXAssertionsTests.m; sourceTree = "<group>"; };
+ D472095211581618003F9546 /* RXMockObjectTests.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RXMockObjectTests.m; sourceTree = "<group>"; };
+ D4C03B471063445800925A75 /* RXAssertions.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RXAssertions.h; sourceTree = "<group>"; };
+ D4C03B481063445800925A75 /* RXAssertions.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RXAssertions.m; sourceTree = "<group>"; };
+ D4C03B491063445800925A75 /* RXAssertions.pch */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RXAssertions.pch; sourceTree = "<group>"; };
+ D4CE0C54116FB8E400FE6B86 /* RXAssertionHelperTests.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RXAssertionHelperTests.m; sourceTree = "<group>"; };
+ D4F3DD2611558CC2008BB0F8 /* RXMockObject.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RXMockObject.h; sourceTree = "<group>"; };
+ D4F3DD2711558CC2008BB0F8 /* RXMockObject.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RXMockObject.m; sourceTree = "<group>"; };
+/* End PBXFileReference section */
+
+/* Begin PBXFrameworksBuildPhase section */
+ D2AAC07C0554694100DB518D /* Frameworks */ = {
+ isa = PBXFrameworksBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ };
+ D442A485106FD94900944F07 /* Frameworks */ = {
+ isa = PBXFrameworksBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ D442A493106FD9BF00944F07 /* libRXAssertions.a in Frameworks */,
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ };
+/* End PBXFrameworksBuildPhase section */
+
+/* Begin PBXGroup section */
+ 034768DFFF38A50411DB9C8B /* Products */ = {
+ isa = PBXGroup;
+ children = (
+ D2AAC07E0554694100DB518D /* libRXAssertions.a */,
+ D442A488106FD94900944F07 /* Tests.octest */,
+ );
+ name = Products;
+ sourceTree = "<group>";
+ };
+ 0867D691FE84028FC02AAC07 /* RXAssertions */ = {
+ isa = PBXGroup;
+ children = (
+ D4C03B471063445800925A75 /* RXAssertions.h */,
+ D4C03B481063445800925A75 /* RXAssertions.m */,
+ D4C03B491063445800925A75 /* RXAssertions.pch */,
+ D442A48D106FD99700944F07 /* RXAssertionsTests.m */,
+ D4CE0C54116FB8E400FE6B86 /* RXAssertionHelperTests.m */,
+ D4F3DD2611558CC2008BB0F8 /* RXMockObject.h */,
+ D4F3DD2711558CC2008BB0F8 /* RXMockObject.m */,
+ D472095211581618003F9546 /* RXMockObjectTests.m */,
+ D442A489106FD94900944F07 /* Tests-Info.plist */,
+ 034768DFFF38A50411DB9C8B /* Products */,
+ );
+ name = RXAssertions;
+ sourceTree = "<group>";
+ };
+/* End PBXGroup section */
+
+/* Begin PBXHeadersBuildPhase section */
+ D2AAC07A0554694100DB518D /* Headers */ = {
+ isa = PBXHeadersBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ D4C03B4A1063445800925A75 /* RXAssertions.h in Headers */,
+ D4F3DD2811558CC2008BB0F8 /* RXMockObject.h in Headers */,
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ };
+/* End PBXHeadersBuildPhase section */
+
+/* Begin PBXNativeTarget section */
+ D2AAC07D0554694100DB518D /* RXAssertions */ = {
+ isa = PBXNativeTarget;
+ buildConfigurationList = 1DEB921E08733DC00010E9CD /* Build configuration list for PBXNativeTarget "RXAssertions" */;
+ buildPhases = (
+ D2AAC07B0554694100DB518D /* Sources */,
+ D2AAC07A0554694100DB518D /* Headers */,
+ D2AAC07C0554694100DB518D /* Frameworks */,
+ );
+ buildRules = (
+ );
+ dependencies = (
+ );
+ name = RXAssertions;
+ productName = RXAssertions;
+ productReference = D2AAC07E0554694100DB518D /* libRXAssertions.a */;
+ productType = "com.apple.product-type.library.static";
+ };
+ D442A487106FD94900944F07 /* Tests */ = {
+ isa = PBXNativeTarget;
+ buildConfigurationList = D442A48C106FD94A00944F07 /* Build configuration list for PBXNativeTarget "Tests" */;
+ buildPhases = (
+ D442A484106FD94900944F07 /* Sources */,
+ D442A483106FD94900944F07 /* Resources */,
+ D442A485106FD94900944F07 /* Frameworks */,
+ D442A486106FD94900944F07 /* ShellScript */,
+ );
+ buildRules = (
+ );
+ dependencies = (
+ D442A490106FD9A400944F07 /* PBXTargetDependency */,
+ );
+ name = Tests;
+ productName = Tests;
+ productReference = D442A488106FD94900944F07 /* Tests.octest */;
+ productType = "com.apple.product-type.bundle";
+ };
+/* End PBXNativeTarget section */
+
+/* Begin PBXProject section */
+ 0867D690FE84028FC02AAC07 /* Project object */ = {
+ isa = PBXProject;
+ buildConfigurationList = 1DEB922208733DC00010E9CD /* Build configuration list for PBXProject "RXAssertions" */;
+ compatibilityVersion = "Xcode 3.1";
+ hasScannedForEncodings = 1;
+ mainGroup = 0867D691FE84028FC02AAC07 /* RXAssertions */;
+ productRefGroup = 034768DFFF38A50411DB9C8B /* Products */;
+ projectDirPath = "";
+ projectRoot = "";
+ targets = (
+ D2AAC07D0554694100DB518D /* RXAssertions */,
+ D442A487106FD94900944F07 /* Tests */,
+ );
+ };
+/* End PBXProject section */
+
+/* Begin PBXResourcesBuildPhase section */
+ D442A483106FD94900944F07 /* Resources */ = {
+ isa = PBXResourcesBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ };
+/* End PBXResourcesBuildPhase section */
+
+/* Begin PBXShellScriptBuildPhase section */
+ D442A486106FD94900944F07 /* ShellScript */ = {
+ isa = PBXShellScriptBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ );
+ inputPaths = (
+ );
+ outputPaths = (
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ shellPath = /bin/sh;
+ shellScript = "# Run the unit tests in this test bundle.\n\"${SYSTEM_DEVELOPER_DIR}/Tools/RunUnitTests\"\n";
+ };
+/* End PBXShellScriptBuildPhase section */
+
+/* Begin PBXSourcesBuildPhase section */
+ D2AAC07B0554694100DB518D /* Sources */ = {
+ isa = PBXSourcesBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ D4C03B4B1063445800925A75 /* RXAssertions.m in Sources */,
+ D4F3DD2911558CC2008BB0F8 /* RXMockObject.m in Sources */,
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ };
+ D442A484106FD94900944F07 /* Sources */ = {
+ isa = PBXSourcesBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ D472095311581618003F9546 /* RXMockObjectTests.m in Sources */,
+ D4CE0C55116FB8E400FE6B86 /* RXAssertionHelperTests.m in Sources */,
+ D415F64311A28E060027AAD8 /* RXAssertionsTests.m in Sources */,
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ };
+/* End PBXSourcesBuildPhase section */
+
+/* Begin PBXTargetDependency section */
+ D442A490106FD9A400944F07 /* PBXTargetDependency */ = {
+ isa = PBXTargetDependency;
+ target = D2AAC07D0554694100DB518D /* RXAssertions */;
+ targetProxy = D442A48F106FD9A400944F07 /* PBXContainerItemProxy */;
+ };
+/* End PBXTargetDependency section */
+
+/* Begin XCBuildConfiguration section */
+ 1DEB921F08733DC00010E9CD /* Debug */ = {
+ isa = XCBuildConfiguration;
+ buildSettings = {
+ ALWAYS_SEARCH_USER_PATHS = NO;
+ COPY_PHASE_STRIP = NO;
+ FRAMEWORK_SEARCH_PATHS = "$(DEVELOPER_LIBRARY_DIR)/Frameworks";
+ GCC_DYNAMIC_NO_PIC = NO;
+ GCC_ENABLE_FIX_AND_CONTINUE = YES;
+ GCC_ENABLE_OBJC_GC = supported;
+ GCC_INCREASE_PRECOMPILED_HEADER_SHARING = YES;
+ GCC_MODEL_TUNING = G5;
+ GCC_OPTIMIZATION_LEVEL = 0;
+ GCC_PRECOMPILE_PREFIX_HEADER = YES;
+ GCC_PREFIX_HEADER = RXAssertions.pch;
+ INSTALL_PATH = /usr/local/lib;
+ ONLY_ACTIVE_ARCH = YES;
+ OTHER_LDFLAGS = (
+ "-ObjC",
+ "-framework",
+ SenTestingKit,
+ "-framework",
+ Foundation,
+ );
+ PRODUCT_NAME = RXAssertions;
+ };
+ name = Debug;
+ };
+ 1DEB922008733DC00010E9CD /* Release */ = {
+ isa = XCBuildConfiguration;
+ buildSettings = {
+ ALWAYS_SEARCH_USER_PATHS = NO;
+ DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
+ FRAMEWORK_SEARCH_PATHS = "$(DEVELOPER_LIBRARY_DIR)/Frameworks";
+ GCC_ENABLE_OBJC_GC = supported;
+ GCC_INCREASE_PRECOMPILED_HEADER_SHARING = YES;
+ GCC_MODEL_TUNING = G5;
+ GCC_PRECOMPILE_PREFIX_HEADER = YES;
+ GCC_PREFIX_HEADER = RXAssertions.pch;
+ INSTALL_PATH = /usr/local/lib;
+ OTHER_LDFLAGS = (
+ "-ObjC",
+ "-framework",
+ SenTestingKit,
+ "-framework",
+ Foundation,
+ );
+ PRODUCT_NAME = RXAssertions;
+ };
+ name = Release;
+ };
+ 1DEB922308733DC00010E9CD /* Debug */ = {
+ isa = XCBuildConfiguration;
+ buildSettings = {
+ ARCHS = "$(ARCHS_STANDARD_32_64_BIT)";
+ GCC_C_LANGUAGE_STANDARD = gnu99;
+ GCC_OPTIMIZATION_LEVEL = 0;
+ GCC_VERSION = com.apple.compilers.llvm.clang.1_0;
+ GCC_WARN_ABOUT_RETURN_TYPE = YES;
+ GCC_WARN_UNUSED_VARIABLE = YES;
+ ONLY_ACTIVE_ARCH = YES;
+ PREBINDING = NO;
+ SDKROOT = macosx10.6;
+ };
+ name = Debug;
+ };
+ 1DEB922408733DC00010E9CD /* Release */ = {
+ isa = XCBuildConfiguration;
+ buildSettings = {
+ ARCHS = "$(ARCHS_STANDARD_32_64_BIT)";
+ GCC_C_LANGUAGE_STANDARD = gnu99;
+ GCC_VERSION = com.apple.compilers.llvm.clang.1_0;
+ GCC_WARN_ABOUT_RETURN_TYPE = YES;
+ GCC_WARN_UNUSED_VARIABLE = YES;
+ PREBINDING = NO;
+ SDKROOT = macosx10.6;
+ };
+ name = Release;
+ };
+ D442A48A106FD94A00944F07 /* Debug */ = {
+ isa = XCBuildConfiguration;
+ buildSettings = {
+ ALWAYS_SEARCH_USER_PATHS = NO;
+ COPY_PHASE_STRIP = NO;
+ FRAMEWORK_SEARCH_PATHS = "$(DEVELOPER_LIBRARY_DIR)/Frameworks";
+ GCC_DYNAMIC_NO_PIC = NO;
+ GCC_ENABLE_FIX_AND_CONTINUE = NO;
+ GCC_ENABLE_OBJC_EXCEPTIONS = YES;
+ GCC_ENABLE_OBJC_GC = supported;
+ GCC_INCREASE_PRECOMPILED_HEADER_SHARING = YES;
+ GCC_MODEL_TUNING = G5;
+ GCC_OPTIMIZATION_LEVEL = 0;
+ GCC_PRECOMPILE_PREFIX_HEADER = YES;
+ GCC_PREFIX_HEADER = RXAssertions.pch;
+ INFOPLIST_FILE = "Tests-Info.plist";
+ INSTALL_PATH = "$(USER_LIBRARY_DIR)/Bundles";
+ OTHER_LDFLAGS = (
+ "-ObjC",
+ "-framework",
+ Cocoa,
+ "-framework",
+ SenTestingKit,
+ );
+ PREBINDING = NO;
+ PRODUCT_NAME = Tests;
+ WRAPPER_EXTENSION = octest;
+ };
+ name = Debug;
+ };
+ D442A48B106FD94A00944F07 /* Release */ = {
+ isa = XCBuildConfiguration;
+ buildSettings = {
+ ALWAYS_SEARCH_USER_PATHS = NO;
+ COPY_PHASE_STRIP = YES;
+ DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
+ FRAMEWORK_SEARCH_PATHS = "$(DEVELOPER_LIBRARY_DIR)/Frameworks";
+ GCC_ENABLE_FIX_AND_CONTINUE = NO;
+ GCC_ENABLE_OBJC_EXCEPTIONS = YES;
+ GCC_ENABLE_OBJC_GC = supported;
+ GCC_INCREASE_PRECOMPILED_HEADER_SHARING = YES;
+ GCC_MODEL_TUNING = G5;
+ GCC_PRECOMPILE_PREFIX_HEADER = YES;
+ GCC_PREFIX_HEADER = RXAssertions.pch;
+ INFOPLIST_FILE = "Tests-Info.plist";
+ INSTALL_PATH = "$(USER_LIBRARY_DIR)/Bundles";
+ OTHER_LDFLAGS = (
+ "-ObjC",
+ "-framework",
+ Cocoa,
+ "-framework",
+ SenTestingKit,
+ );
+ PREBINDING = NO;
+ PRODUCT_NAME = Tests;
+ WRAPPER_EXTENSION = octest;
+ ZERO_LINK = NO;
+ };
+ name = Release;
+ };
+/* End XCBuildConfiguration section */
+
+/* Begin XCConfigurationList section */
+ 1DEB921E08733DC00010E9CD /* Build configuration list for PBXNativeTarget "RXAssertions" */ = {
+ isa = XCConfigurationList;
+ buildConfigurations = (
+ 1DEB921F08733DC00010E9CD /* Debug */,
+ 1DEB922008733DC00010E9CD /* Release */,
+ );
+ defaultConfigurationIsVisible = 0;
+ defaultConfigurationName = Release;
+ };
+ 1DEB922208733DC00010E9CD /* Build configuration list for PBXProject "RXAssertions" */ = {
+ isa = XCConfigurationList;
+ buildConfigurations = (
+ 1DEB922308733DC00010E9CD /* Debug */,
+ 1DEB922408733DC00010E9CD /* Release */,
+ );
+ defaultConfigurationIsVisible = 0;
+ defaultConfigurationName = Release;
+ };
+ D442A48C106FD94A00944F07 /* Build configuration list for PBXNativeTarget "Tests" */ = {
+ isa = XCConfigurationList;
+ buildConfigurations = (
+ D442A48A106FD94A00944F07 /* Debug */,
+ D442A48B106FD94A00944F07 /* Release */,
+ );
+ defaultConfigurationIsVisible = 0;
+ defaultConfigurationName = Release;
+ };
+/* End XCConfigurationList section */
+ };
+ rootObject = 0867D690FE84028FC02AAC07 /* Project object */;
+}
67 RXAssertionsTests.m
@@ -0,0 +1,67 @@
+// RXAssertionsTests.m
+// Created by Rob Rix on 2009-09-27
+// Copyright 2009 Monochrome Industries
+
+#import "RXAssertions.h"
+
+@interface RXAssertionsTests : SenTestCase {
+ NSUInteger incrementedValue;
+}
+@end
+
+@implementation RXAssertionsTests
+
+-(void)setUp {
+ incrementedValue = 0;
+}
+
+-(NSUInteger)incrementedValue {
+ return incrementedValue++;
+}
+
+#if RX_DEMONSTRATE_TEST_FAILURES
+-(void)testDemonstrateFailures {
+ BOOL condition = NO;
+ RXAssert(condition);
+ condition = YES;
+ RXAssertFalse(condition);
+ id actual = @"one";
+ id expected = @"two";
+ RXAssertEquals(actual, expected);
+ id unexpected = @"one";
+ RXAssertNotEquals(actual, unexpected);
+
+ id object = @"object";
+ RXAssertNil(object);
+ object = nil;
+ RXAssertNotNil(object);
+}
+#endif
+
+#if RX_DEMONSTRATE_TEST_FAILURES && RX_DEMONSTRATE_TEST_FAILURE_MESSAGES
+-(void)testCanAddOptionalFailureMessages {
+ BOOL condition = NO;
+ RXAssert(condition, @"This is a demonstration of an %@ failure", @"RXAssert");
+ RXAssertFalse(!condition, @"This is a demonstration of an %@ failure", @"RXAssertFalse");
+
+ id actual = @"one";
+ id expected = @"two";
+ RXAssertEquals(actual, expected, @"This is a demonstration of an %@ failure.", @"RXAssertEquals");
+ id unexpected = @"one";
+ RXAssertNotEquals(actual, unexpected, @"This is a demonstration of an %@ failure.", @"RXAssertNotEquals");
+
+ id object = @"object";
+ RXAssertNil(object, @"This is a demonstration of an %@ failure.", @"RXAssertNil");
+ object = nil;
+ RXAssertNotNil(object, @"This is a demonstration of an %@ failure.", @"RXAssertNotNil");
+}
+#endif
+
+-(void)testDoesNotCauseExtraSideEffects {
+ RXAssert([self incrementedValue] == 0);
+ RXAssertFalse([self incrementedValue] == 0);
+ RXAssertEquals([self incrementedValue], 2);
+ RXAssertEquals([self incrementedValue], 3);
+}
+
+@end
24 RXMockObject.h
@@ -0,0 +1,24 @@
+// RXMockObject.h
+// Created by Rob Rix on 2010-03-20
+// Copyright 2010 Monochrome Industries
+
+#import <Foundation/Foundation.h>
+
+// use RXMockNull to represent a nil return or a nil value in an argument list.
+// this is used instead of +[NSNull null] to let us use +[NSNull null] in our tests themselves.
+extern NSString * const RXMockNull;
+
+@interface RXMockObject : NSObject {
+ NSMutableDictionary *responses;
+}
+
++(RXMockObject *)mockObject;
++(RXMockObject *)mockObjectWithResponseObject:(id)response forSelector:(SEL)selector;
++(RXMockObject *)mockObjectWithResponseObject:(id)response forSelector:(SEL)selector withArgument:(id)argument;
++(RXMockObject *)mockObjectWithResponseObject:(id)response forSelector:(SEL)selector withArguments:(NSArray *)arguments;
+
+-(void)setResponseObject:(id)object forSelector:(SEL)selector;
+-(void)setResponseObject:(id)object forSelector:(SEL)selector withArgument:(id)argument;
+-(void)setResponseObject:(id)response forSelector:(SEL)selector withArguments:(NSArray *)arguments;
+
+@end
101 RXMockObject.m
@@ -0,0 +1,101 @@
+// RXMockObject.m
+// Created by Rob Rix on 2010-03-20
+// Copyright 2010 Monochrome Industries
+
+#import "RXMockObject.h"
+#import <objc/runtime.h>
+
+NSString * const RXMockNull = @"RXMockNull";
+
+@implementation RXMockObject
+
+-(id)init {
+ if(self = [super init]) {
+ responses = [[NSMutableDictionary alloc] init];
+ }
+ return self;
+}
+
+-(void)dealloc {
+ [responses release];
+ [super dealloc];
+}
+
+
++(RXMockObject *)mockObject {
+ return [[[self alloc] init] autorelease];
+}
+
++(RXMockObject *)mockObjectWithResponseObject:(id)response forSelector:(SEL)selector {
+ RXMockObject *object = [[[self alloc] init] autorelease];
+ [object setResponseObject: response forSelector: selector];
+ return object;
+}
+
++(RXMockObject *)mockObjectWithResponseObject:(id)response forSelector:(SEL)selector withArgument:(id)argument {
+ RXMockObject *object = [[[self alloc] init] autorelease];
+ [object setResponseObject: response forSelector: selector withArgument: argument];
+ return object;
+}
+
++(RXMockObject *)mockObjectWithResponseObject:(id)response forSelector:(SEL)selector withArguments:(NSArray *)arguments {
+ RXMockObject *object = [[[self alloc] init] autorelease];
+ [object setResponseObject: response forSelector: selector withArguments: arguments];
+ return object;
+}
+
+
+-(void)setResponseObject:(id)response forSelector:(SEL)selector {
+ [self setResponseObject: response forSelector: selector withArguments: [NSArray array]];
+
+}
+
+-(void)setResponseObject:(id)response forSelector:(SEL)selector withArgument:(id)argument {
+ [self setResponseObject: response forSelector: selector withArguments: [NSArray arrayWithObject: argument ?: RXMockNull]];
+}
+
+-(void)setResponseObject:(id)response forSelector:(SEL)selector withArguments:(NSArray *)arguments {
+ NSMutableDictionary *responsesByArguments = [responses objectForKey: NSStringFromSelector(selector)];
+ if(!responsesByArguments) {
+ [responses setObject: (responsesByArguments = [NSMutableDictionary dictionary]) forKey: NSStringFromSelector(selector)];
+ }
+ [responsesByArguments setObject: response ?: RXMockNull forKey: arguments];
+}
+
+-(id)responsesForSelector:(SEL)selector {
+ return [responses objectForKey: NSStringFromSelector(selector)];
+}
+
+-(id)responseForSelector:(SEL)selector withArguments:(NSArray *)arguments {
+ return [[self responsesForSelector: selector] objectForKey: arguments];
+}
+
+
+-(NSMethodSignature *)methodSignatureForSelector:(SEL)selector {
+ NSMethodSignature *signature = nil;
+ if([self responsesForSelector: selector]) {
+ NSUInteger arity = ([NSStringFromSelector(selector) componentsSeparatedByString: @":"].count - 1u);
+ NSMutableArray *argumentTypes = [NSMutableArray array];
+ for(NSUInteger i = 0; i < arity; i++) {
+ [argumentTypes addObject: [NSString stringWithUTF8String: @encode(id)]];
+ }
+ signature = [NSMethodSignature signatureWithObjCTypes: [[NSString stringWithFormat: @"%s%s%s%@", @encode(id), @encode(SEL), @encode(id), [argumentTypes componentsJoinedByString: @""]] UTF8String]];
+ }
+ return signature;
+}
+
+-(void)forwardInvocation:(NSInvocation *)invocation {
+ if([self responsesForSelector: invocation.selector]) {
+ NSMutableArray *arguments = [NSMutableArray array];
+ for(NSUInteger i = 2; i < invocation.methodSignature.numberOfArguments; i++) {
+ id argument;
+ [invocation getArgument: &argument atIndex: i];
+ [arguments addObject: argument ?: RXMockNull];
+ }
+ id response = [self responseForSelector: invocation.selector withArguments: [arguments copy]];
+ if(response == RXMockNull) response = nil;
+ [invocation setReturnValue: &response];
+ }
+}
+
+@end
63 RXMockObjectTests.m
@@ -0,0 +1,63 @@
+// RXMockObjectTests.m
+// Created by Rob Rix on 2010-03-22
+// Copyright 2010 Monochrome Industries
+
+#import "RXAssertions.h"
+#import "RXMockObject.h"
+
+@interface NSObject (RXMockObjectTests)
+-(id)nullary;
+-(id)unary:(id)arg;
+-(id)binary:(id)arg1 method:(id)arg2;
+@end
+
+@interface RXMockObjectTests : SenTestCase {
+ id mock;
+}
+@end
+
+@implementation RXMockObjectTests
+
+-(void)setUp {
+ mock = [RXMockObject mockObject];
+}
+
+-(void)testRespondsToNullaryMessagesWithTheGivenObject {
+ [mock setResponseObject: @"nullary response" forSelector: @selector(nullary)];
+ RXAssertEquals([mock nullary], @"nullary response");
+}
+
+-(void)testRespondsToUnaryMessagesWithTheGivenObject {
+ [mock setResponseObject: @"result 1" forSelector: @selector(unary:) withArgument: @"argument 1"];
+ [mock setResponseObject: @"result 2" forSelector: @selector(unary:) withArgument: @"argument 2"];
+ RXAssertEquals([mock unary: @"argument 1"], @"result 1");
+ RXAssertEquals([mock unary: @"argument 2"], @"result 2");
+ RXAssertNil([mock unary: @"not specified"]);
+ RXAssertNil([mock unary: nil]);
+}
+
+-(void)testRespondsToMessagesWithNilArguments {
+ [mock setResponseObject: @"result 1" forSelector: @selector(unary:) withArgument: nil];
+ [mock setResponseObject: @"result 2" forSelector: @selector(unary:) withArgument: @"argument 2"];
+ RXAssertEquals([mock unary: nil], @"result 1");
+ RXAssertEquals([mock unary: @"argument 2"], @"result 2");
+ RXAssertNil([mock unary: @"not specified"]);
+}
+
+
+-(void)testAcceptsNilResponses {
+ [mock setResponseObject: nil forSelector: @selector(nullary)];
+ [mock setResponseObject: nil forSelector: @selector(unary:) withArgument: nil];
+ [mock setResponseObject: @"" forSelector: @selector(unary:) withArgument: @""];
+ [mock setResponseObject: nil forSelector: @selector(binary:method:) withArguments: [NSArray arrayWithObjects: RXMockNull, RXMockNull, nil]];
+ [mock setResponseObject: @"" forSelector: @selector(binary:method:) withArguments: [NSArray arrayWithObjects: @"", RXMockNull, nil]];
+ [mock setResponseObject: @"" forSelector: @selector(binary:method:) withArguments: [NSArray arrayWithObjects: RXMockNull, @"", nil]];
+ RXAssertNil([mock nullary]);
+ RXAssertNil([mock unary: nil]);
+ RXAssertNotNil([mock unary: @""]);
+ RXAssertNil([mock binary: nil method: nil]);
+ RXAssertNotNil([mock binary: @"" method: nil]);
+ RXAssertNotNil([mock binary: nil method: @""]);
+}
+
+@end
2  Tasks.taskpaper
@@ -0,0 +1,2 @@
+Documentation:
+- document the error messages that result from each assertion failure, to give people a feel for what RXAssertions gives you out of the box. @done(2009-09-27)
22 Tests-Info.plist
@@ -0,0 +1,22 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
+<plist version="1.0">
+<dict>
+ <key>CFBundleDevelopmentRegion</key>
+ <string>English</string>
+ <key>CFBundleExecutable</key>
+ <string>${EXECUTABLE_NAME}</string>
+ <key>CFBundleIdentifier</key>
+ <string>com.yourcompany.${PRODUCT_NAME:rfc1034identifier}</string>
+ <key>CFBundleInfoDictionaryVersion</key>
+ <string>6.0</string>
+ <key>CFBundlePackageType</key>
+ <string>BNDL</string>
+ <key>CFBundleShortVersionString</key>
+ <string>1.0</string>
+ <key>CFBundleSignature</key>
+ <string>????</string>
+ <key>CFBundleVersion</key>
+ <string>1</string>
+</dict>
+</plist>
Please sign in to comment.
Something went wrong with that request. Please try again.