This commit is contained in:
giuseppenuc committed 2016-02-24 16:56:39 +01:00
1 parent d281d765ea
commit 5b074a5176
1261 files changed
+199158 -7303

No files matched your search

@@ -0,0 +1,42 @@
//
// OCHamcrest - HCAssertThat.h
// Copyright 2012 hamcrest.org. See LICENSE.txt
//
// Created by: Jon Reid, http://qualitycoding.org/
// Docs: http://hamcrest.github.com/OCHamcrest/
// Source: https://github.com/hamcrest/OCHamcrest
//
#import <objc/objc-api.h>
@protocol HCMatcher;
OBJC_EXPORT void HC_assertThatWithLocation(id testCase, id actual, id<HCMatcher> matcher,
const char *fileName, int lineNumber);
#define HC_assertThat(actual, matcher) \
HC_assertThatWithLocation(self, actual, matcher, __FILE__, __LINE__)
/**
assertThat(actual, matcher) -
Asserts that actual value satisfies matcher.
@param actual The object to evaluate as the actual value.
@param matcher The matcher to satisfy as the expected condition.
@c assertThat passes the actual value to the matcher for evaluation. If the matcher is not
satisfied, an exception is thrown describing the mismatch.
@c assertThat is designed to integrate well with OCUnit and other unit testing frameworks.
Unmet assertions are reported as test failures. In Xcode, these failures can be clicked to
reveal the line of the assertion.
In the event of a name clash, don't \#define @c HC_SHORTHAND and use the synonym
@c HC_assertThat instead.
@ingroup integration
*/
#ifdef HC_SHORTHAND
#define assertThat HC_assertThat
#endif
@@ -0,0 +1,89 @@
//
// OCHamcrest - HCAssertThat.m
// Copyright 2012 hamcrest.org. See LICENSE.txt
//
// Created by: Jon Reid, http://qualitycoding.org/
// Docs: http://hamcrest.github.com/OCHamcrest/
// Source: https://github.com/hamcrest/OCHamcrest
//
#import "HCAssertThat.h"
#import "HCStringDescription.h"
#import "HCMatcher.h"
/**
Create OCUnit failure
With OCUnit's extension to NSException, this is effectively the same as
@code
[NSException failureInFile: [NSString stringWithUTF8String:fileName]
atLine: lineNumber
withDescription: description]
@endcode
except we use an NSInvocation so that OCUnit (SenTestingKit) does not have to be linked.
*/
static NSException *createOCUnitException(const char* fileName, int lineNumber, __unsafe_unretained NSString *description)
{
__unsafe_unretained NSException *result = nil;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wundeclared-selector"
SEL selector = @selector(failureInFile:atLine:withDescription:);
#pragma clang diagnostic pop
NSMethodSignature *signature = [[NSException class] methodSignatureForSelector:selector];
NSInvocation *invocation = [NSInvocation invocationWithMethodSignature:signature];
[invocation setTarget:[NSException class]];
[invocation setSelector:selector];
__unsafe_unretained id fileArg = @(fileName);
[invocation setArgument:&fileArg atIndex:2];
[invocation setArgument:&lineNumber atIndex:3];
[invocation setArgument:&description atIndex:4];
[invocation invoke];
[invocation getReturnValue:&result];
return result;
}
static NSException *createAssertThatFailure(const char *fileName, int lineNumber, NSString *description)
{
// If the Hamcrest client has linked to OCUnit, generate an OCUnit failure.
if (NSClassFromString(@"SenTestCase") != Nil)
return createOCUnitException(fileName, lineNumber, description);
NSString *failureReason = [NSString stringWithFormat:@"%s:%d: matcher error: %@",
fileName, lineNumber, description];
return [NSException exceptionWithName:@"Hamcrest Error" reason:failureReason userInfo:nil];
}
#pragma mark -
// As of 2010-09-09, the iPhone simulator has a bug where you can't catch
// exceptions when they are thrown across NSInvocation boundaries. (See
// dmaclach's comment at http://openradar.appspot.com/8081169 ) So instead of
// using an NSInvocation to call failWithException:assertThatFailure without
// linking in OCUnit, we simply pretend it exists on NSObject.
@interface NSObject (HCExceptionBugHack)
- (void)failWithException:(NSException *)exception;
@end
void HC_assertThatWithLocation(id testCase, id actual, id<HCMatcher> matcher,
const char *fileName, int lineNumber)
{
if (![matcher matches:actual])
{
HCStringDescription *description = [HCStringDescription stringDescription];
[[[description appendText:@"Expected "]
appendDescriptionOf:matcher]
appendText:@", but "];
[matcher describeMismatchOf:actual to:description];
NSException *assertThatFailure = createAssertThatFailure(fileName, lineNumber,
[description description]);
[testCase failWithException:assertThatFailure];
}
}
@@ -0,0 +1,33 @@
//
// OCHamcrest - HCBaseDescription.h
// Copyright 2012 hamcrest.org. See LICENSE.txt
//
// Created by: Jon Reid, http://qualitycoding.org/
// Docs: http://hamcrest.github.com/OCHamcrest/
// Source: https://github.com/hamcrest/OCHamcrest
//
#import <Foundation/Foundation.h>
#import <OCHamcrest/HCDescription.h>
/**
Base class for all HCDescription implementations.
@ingroup core
*/
@interface HCBaseDescription : NSObject <HCDescription>
@end
/**
Methods that must be provided by subclasses of HCBaseDescription.
*/
@interface HCBaseDescription (SubclassMustImplement)
/**
Append the string @a str to the description.
*/
- (void)append:(NSString *)str;
@end
@@ -0,0 +1,107 @@
//
// OCHamcrest - HCBaseDescription.m
// Copyright 2012 hamcrest.org. See LICENSE.txt
//
// Created by: Jon Reid, http://qualitycoding.org/
// Docs: http://hamcrest.github.com/OCHamcrest/
// Source: https://github.com/hamcrest/OCHamcrest
//
#import "HCBaseDescription.h"
#import "HCMatcher.h"
@implementation HCBaseDescription
- (id<HCDescription>)appendText:(NSString *)text
{
[self append:text];
return self;
}
- (id<HCDescription>)appendDescriptionOf:(id)value
{
if (value == nil)
[self append:@"nil"];
else if ([value conformsToProtocol:@protocol(HCSelfDescribing)])
[value describeTo:self];
else if ([value isKindOfClass:[NSString class]])
[self toCSyntaxString:value];
else
[self appendObjectDescriptionOf:value];
return self;
}
- (id<HCDescription>)appendObjectDescriptionOf:(id)value
{
NSString *description = [value description];
NSUInteger descriptionLength = [description length];
if (descriptionLength == 0)
[self append:[NSString stringWithFormat:@"<%@: %p>", NSStringFromClass([value class]), (__bridge void *)value]];
else if ([description characterAtIndex:0] == '<'
&& [description characterAtIndex:descriptionLength - 1] == '>')
{
[self append:description];
}
else
{
[self append:@"<"];
[self append:description];
[self append:@">"];
}
return self;
}
- (id<HCDescription>)appendList:(NSArray *)values
start:(NSString *)start
separator:(NSString *)separator
end:(NSString *)end
{
BOOL separate = NO;
[self append:start];
for (id item in values)
{
if (separate)
[self append:separator];
[self appendDescriptionOf:item];
separate = YES;
}
[self append:end];
return self;
}
- (void)toCSyntaxString:(NSString *)unformatted
{
[self append:@"\""];
NSUInteger length = [unformatted length];
for (NSUInteger index = 0; index < length; ++index)
[self toCSyntax:[unformatted characterAtIndex:index]];
[self append:@"\""];
}
- (void)toCSyntax:(unichar)ch
{
switch (ch)
{
case '"':
[self append:@"\\\""];
break;
case '\n':
[self append:@"\\n"];
break;
case '\r':
[self append:@"\\r"];
break;
case '\t':
[self append:@"\\t"];
break;
default:
[self append:[NSString stringWithCharacters:&ch length:1]];
break;
}
}
@end
@@ -0,0 +1,27 @@
//
// OCHamcrest - HCBaseMatcher.h
// Copyright 2012 hamcrest.org. See LICENSE.txt
//
// Created by: Jon Reid, http://qualitycoding.org/
// Docs: http://hamcrest.github.com/OCHamcrest/
// Source: https://github.com/hamcrest/OCHamcrest
//
#import <Foundation/Foundation.h>
#import <OCHamcrest/HCMatcher.h>
#import <objc/objc-api.h> // Convenience header, to provide OBJC_EXPORT
/**
Base class for all HCMatcher implementations.
Most implementations can just implement @c -matches: and let
<code>-matches:describingMismatchTo:</code> call it. But if it makes more sense to generate the
mismatch description during the matching, override <code>-matches:describingMismatchTo:</code>
and have @c -matches: call it with a @c nil description.
@ingroup core
*/
@interface HCBaseMatcher : NSObject <HCMatcher>
@end
@@ -0,0 +1,55 @@
//
// OCHamcrest - HCBaseMatcher.m
// Copyright 2012 hamcrest.org. See LICENSE.txt
//
// Created by: Jon Reid, http://qualitycoding.org/
// Docs: http://hamcrest.github.com/OCHamcrest/
// Source: https://github.com/hamcrest/OCHamcrest
//
#import "HCBaseMatcher.h"
#import "HCStringDescription.h"
#define ABSTRACT_METHOD [self subclassResponsibility:_cmd]
@implementation HCBaseMatcher
- (NSString *)description
{
return [HCStringDescription stringFrom:self];
}
- (BOOL)matches:(id)item
{
ABSTRACT_METHOD;
return NO;
}
- (BOOL)matches:(id)item describingMismatchTo:(id<HCDescription>)mismatchDescription
{
BOOL matchResult = [self matches:item];
if (!matchResult)
[self describeMismatchOf:item to:mismatchDescription];
return matchResult;
}
- (void)describeMismatchOf:(id)item to:(id<HCDescription>)mismatchDescription
{
[[mismatchDescription appendText:@"was "] appendDescriptionOf:item];
}
- (void)describeTo:(id<HCDescription>)description
{
ABSTRACT_METHOD;
}
- (void)subclassResponsibility:(SEL)command
{
NSString *className = NSStringFromClass([self class]);
[NSException raise:NSGenericException
format:@"-[%@ %@] not implemented", className, NSStringFromSelector(command)];
}
@end
@@ -0,0 +1,48 @@
//
// OCHamcrest - HCDescription.h
// Copyright 2012 hamcrest.org. See LICENSE.txt
//
// Created by: Jon Reid, http://qualitycoding.org/
// Docs: http://hamcrest.github.com/OCHamcrest/
// Source: https://github.com/hamcrest/OCHamcrest
//
#import <Foundation/Foundation.h>
/**
A description of an HCMatcher.
An HCMatcher will describe itself to a description which can later be used for reporting.
@ingroup core
*/
@protocol HCDescription <NSObject>
/**
Appends some plain text to the description.
@return @c self, for chaining.
*/
- (id<HCDescription>)appendText:(NSString *)text;
/**
Appends description of given value to @c self.
If the value implements the @ref HCSelfDescribing protocol, then it will be used.
@return @c self, for chaining.
*/
- (id<HCDescription>)appendDescriptionOf:(id)value;
/**
Appends a list of objects to the description.
@return @c self, for chaining.
*/
- (id<HCDescription>)appendList:(NSArray *)values
start:(NSString *)start
separator:(NSString *)separator
end:(NSString *)end;
@end
@@ -0,0 +1,56 @@
//
// OCHamcrest - HCMatcher.h
// Copyright 2012 hamcrest.org. See LICENSE.txt
//
// Created by: Jon Reid, http://qualitycoding.org/
// Docs: http://hamcrest.github.com/OCHamcrest/
// Source: https://github.com/hamcrest/OCHamcrest
//
#import "HCSelfDescribing.h"
/**
A matcher over acceptable values.
A matcher is able to describe itself to give feedback when it fails.
HCMatcher implementations should @b not directly implement this protocol.
Instead, @b extend the HCBaseMatcher class, which will ensure that the HCMatcher API can grow
to support new features and remain compatible with all HCMatcher implementations.
@ingroup core
*/
@protocol HCMatcher <HCSelfDescribing>
/**
Evaluates the matcher for argument @a item.
@param item The object against which the matcher is evaluated.
@return @c YES if @a item matches, otherwise @c NO.
*/
- (BOOL)matches:(id)item;
/**
Evaluates the matcher for argument @a item.
@param item The object against which the matcher is evaluated.
@param mismatchDescription The description to be built or appended to if @a item does not match.
@return @c YES if @a item matches, otherwise @c NO.
*/
- (BOOL)matches:(id)item describingMismatchTo:(id<HCDescription>)mismatchDescription;
/**
Generates a description of why the matcher has not accepted the item.
The description will be part of a larger description of why a matching failed, so it should be
concise.
This method assumes that @c matches:item is false, but will not check this.
@param item The item that the HCMatcher has rejected.
@param mismatchDescription The description to be built or appended to.
*/
- (void)describeMismatchOf:(id)item to:(id<HCDescription>)mismatchDescription;
@end
@@ -0,0 +1,32 @@
//
// OCHamcrest - HCSelfDescribing.h
// Copyright 2012 hamcrest.org. See LICENSE.txt
//
// Created by: Jon Reid, http://qualitycoding.org/
// Docs: http://hamcrest.github.com/OCHamcrest/
// Source: https://github.com/hamcrest/OCHamcrest
//
#import <Foundation/Foundation.h>
@protocol HCDescription;
/**
The ability of an object to describe itself.
@ingroup core
*/
@protocol HCSelfDescribing <NSObject>
/**
Generates a description of the object.
The description may be part of a description of a larger object of which this is just a
component, so it should be worded appropriately.
@param description The description to be built or appended to.
*/
- (void)describeTo:(id<HCDescription>)description;
@end
@@ -0,0 +1,43 @@
//
// OCHamcrest - HCStringDescription.h
// Copyright 2012 hamcrest.org. See LICENSE.txt
//
// Created by: Jon Reid, http://qualitycoding.org/
// Docs: http://hamcrest.github.com/OCHamcrest/
// Source: https://github.com/hamcrest/OCHamcrest
//
#import <OCHamcrest/HCBaseDescription.h>
@protocol HCSelfDescribing;
/**
An HCDescription that is stored as a string.
@ingroup core
*/
@interface HCStringDescription : HCBaseDescription
{
NSMutableString *accumulator;
}
/**
Returns the description of an HCSelfDescribing object as a string.
@param selfDescribing The object to be described.
@return The description of the object.
*/
+ (NSString *)stringFrom:(id<HCSelfDescribing>)selfDescribing;
/**
Returns an empty description.
*/
+ (HCStringDescription *)stringDescription;
/**
Returns an initialized HCStringDescription object that is empty.
*/
- (id)init;
@end
@@ -0,0 +1,47 @@
//
// OCHamcrest - HCStringDescription.m
// Copyright 2012 hamcrest.org. See LICENSE.txt
//
// Created by: Jon Reid, http://qualitycoding.org/
// Docs: http://hamcrest.github.com/OCHamcrest/
// Source: https://github.com/hamcrest/OCHamcrest
//
#import "HCStringDescription.h"
#import "HCSelfDescribing.h"
@implementation HCStringDescription
+ (NSString *)stringFrom:(id<HCSelfDescribing>)selfDescribing
{
HCStringDescription *description = [HCStringDescription stringDescription];
[description appendDescriptionOf:selfDescribing];
return [description description];
}
+ (HCStringDescription *)stringDescription
{
return [[HCStringDescription alloc] init];
}
- (id)init
{
self = [super init];
if (self)
accumulator = [[NSMutableString alloc] init];
return self;
}
- (NSString *)description
{
return accumulator;
}
- (void)append:(NSString *)str
{
[accumulator appendString:str];
}
@end
@@ -0,0 +1,23 @@
//
// OCHamcrest - HCCollectMatchers.h
// Copyright 2012 hamcrest.org. See LICENSE.txt
//
// Created by: Jon Reid, http://qualitycoding.org/
// Docs: http://hamcrest.github.com/OCHamcrest/
// Source: https://github.com/hamcrest/OCHamcrest
//
#import <Foundation/Foundation.h>
#import <objc/objc-api.h>
#import <stdarg.h>
@protocol HCMatcher;
/**
Returns an array of matchers from a variable-length comma-separated list terminated by @c nil.
@ingroup helpers
*/
OBJC_EXPORT NSMutableArray *HCCollectMatchers(id item1, va_list args);
@@ -0,0 +1,27 @@
//
// OCHamcrest - HCCollectMatchers.m
// Copyright 2012 hamcrest.org. See LICENSE.txt
//
// Created by: Jon Reid, http://qualitycoding.org/
// Docs: http://hamcrest.github.com/OCHamcrest/
// Source: https://github.com/hamcrest/OCHamcrest
//
#import "HCCollectMatchers.h"
#import "HCWrapInMatcher.h"
NSMutableArray *HCCollectMatchers(id item, va_list args)
{
NSMutableArray *matcherList = [NSMutableArray arrayWithObject:HCWrapInMatcher(item)];
item = va_arg(args, id);
while (item != nil)
{
[matcherList addObject:HCWrapInMatcher(item)];
item = va_arg(args, id);
}
return matcherList;
}
@@ -0,0 +1,57 @@
//
// OCHamcrest - HCInvocationMatcher.h
// Copyright 2012 hamcrest.org. See LICENSE.txt
//
// Created by: Jon Reid, http://qualitycoding.org/
// Docs: http://hamcrest.github.com/OCHamcrest/
// Source: https://github.com/hamcrest/OCHamcrest
//
#import <OCHamcrest/HCBaseMatcher.h>
/**
Supporting class for matching a feature of an object.
Tests whether the result of passing a given invocation to the value satisfies a given matcher.
@ingroup helpers
*/
@interface HCInvocationMatcher : HCBaseMatcher
{
NSInvocation *invocation;
id<HCMatcher> subMatcher;
BOOL shortMismatchDescription;
}
/**
Determines whether a mismatch will be described in short form.
Default is long form, which describes the object, the name of the invocation, and the
sub-matcher's mismatch diagnosis. Short form only has the sub-matcher's mismatch diagnosis.
*/
@property (assign, nonatomic) BOOL shortMismatchDescription;
/**
Helper method for creating an invocation.
A class is specified only so we can determine the method signature.
*/
+ (NSInvocation *)invocationForSelector:(SEL)selector onClass:(Class)aClass;
/**
Returns an HCInvocationMatcher object initialized with an invocation and a matcher.
*/
- (id)initWithInvocation:(NSInvocation *)anInvocation matching:(id<HCMatcher>)aMatcher;
/**
Invokes stored invocation on given item and returns the result.
*/
- (id)invokeOn:(id)item;
/**
Returns string representation of the invocation's selector.
*/
- (NSString *)stringFromSelector;
@end
@@ -0,0 +1,85 @@
//
// OCHamcrest - HCInvocationMatcher.m
// Copyright 2012 hamcrest.org. See LICENSE.txt
//
// Created by: Jon Reid, http://qualitycoding.org/
// Docs: http://hamcrest.github.com/OCHamcrest/
// Source: https://github.com/hamcrest/OCHamcrest
//
#import "HCInvocationMatcher.h"
#import "HCDescription.h"
@implementation HCInvocationMatcher
@synthesize shortMismatchDescription;
+ (NSInvocation *)invocationForSelector:(SEL)selector onClass:(Class)aClass
{
NSMethodSignature* signature = [aClass instanceMethodSignatureForSelector:selector];
NSInvocation *invocation = [NSInvocation invocationWithMethodSignature:signature];
[invocation setSelector:selector];
return invocation;
}
- (id)initWithInvocation:(NSInvocation *)anInvocation matching:(id<HCMatcher>)aMatcher
{
self = [super init];
if (self)
{
invocation = anInvocation;
subMatcher = aMatcher;
}
return self;
}
- (NSString *)stringFromSelector
{
return NSStringFromSelector([invocation selector]);
}
- (id)invokeOn:(id)item
{
__unsafe_unretained id result = nil;
[invocation invokeWithTarget:item];
[invocation getReturnValue:&result];
return result;
}
- (BOOL)matches:(id)item
{
if (![item respondsToSelector:[invocation selector]])
return NO;
return [subMatcher matches:[self invokeOn:item]];
}
- (void)describeMismatchOf:(id)item to:(id<HCDescription>)mismatchDescription
{
if (![item respondsToSelector:[invocation selector]])
[super describeMismatchOf:item to:mismatchDescription];
else
{
if (!shortMismatchDescription)
{
[[[[mismatchDescription appendDescriptionOf:item]
appendText:@" "]
appendText:[self stringFromSelector]]
appendText:@" "];
}
[subMatcher describeMismatchOf:[self invokeOn:item] to:mismatchDescription];
}
}
- (void)describeTo:(id<HCDescription>)description
{
[[[[description appendText:@"an object with "]
appendText:[self stringFromSelector]]
appendText:@" "]
appendDescriptionOf:subMatcher];
}
@end
@@ -0,0 +1,19 @@
//
// OCHamcrest - HCRequireNonNilObject.h
// Copyright 2012 hamcrest.org. See LICENSE.txt
//
// Created by: Jon Reid, http://qualitycoding.org/
// Docs: http://hamcrest.github.com/OCHamcrest/
// Source: https://github.com/hamcrest/OCHamcrest
//
#import <Foundation/Foundation.h>
#import <objc/objc-api.h>
/**
Throws an NSException if @a obj is @c nil.
@ingroup helpers
*/
OBJC_EXPORT void HCRequireNonNilObject(id obj);
@@ -0,0 +1,21 @@
//
// OCHamcrest - HCRequireNonNilObject.m
// Copyright 2012 hamcrest.org. See LICENSE.txt
//
// Created by: Jon Reid, http://qualitycoding.org/
// Docs: http://hamcrest.github.com/OCHamcrest/
// Source: https://github.com/hamcrest/OCHamcrest
//
#import "HCRequireNonNilObject.h"
void HCRequireNonNilObject(id obj)
{
if (obj == nil)
{
@throw [NSException exceptionWithName:@"NilObject"
reason:@"Must be non-nil object"
userInfo:nil];
}
}
@@ -0,0 +1,21 @@
//
// OCHamcrest - HCRequireNonNilString.h
// Copyright 2012 hamcrest.org. See LICENSE.txt
//
// Created by: Jon Reid, http://qualitycoding.org/
// Docs: http://hamcrest.github.com/OCHamcrest/
// Source: https://github.com/hamcrest/OCHamcrest
//
#import <Foundation/Foundation.h>
#import <objc/objc-api.h>
/**
Throws an NSException if @a string is @c nil.
@b Deprecated: Use @ref HCRequireNonNilObject instead.
@ingroup helpers
*/
OBJC_EXPORT void HCRequireNonNilString(NSString *string) __attribute__((deprecated));
@@ -0,0 +1,21 @@
//
// OCHamcrest - HCRequireNonNilString.m
// Copyright 2012 hamcrest.org. See LICENSE.txt
//
// Created by: Jon Reid, http://qualitycoding.org/
// Docs: http://hamcrest.github.com/OCHamcrest/
// Source: https://github.com/hamcrest/OCHamcrest
//
#import "HCRequireNonNilString.h"
void HCRequireNonNilString(NSString *string)
{
if (string == nil)
{
@throw [NSException exceptionWithName:@"NotAString"
reason:@"Must be non-nil string"
userInfo:nil];
}
}
@@ -0,0 +1,22 @@
//
// OCHamcrest - HCWrapInMatcher.h
// Copyright 2012 hamcrest.org. See LICENSE.txt
//
// Created by: Jon Reid, http://qualitycoding.org/
// Docs: http://hamcrest.github.com/OCHamcrest/
// Source: https://github.com/hamcrest/OCHamcrest
//
#import <objc/objc-api.h>
@protocol HCMatcher;
/**
Wraps argument in a matcher, if necessary.
@return The argument as-if if it is already a matcher, otherwise wrapped in an @ref equalTo matcher.
@ingroup helpers
*/
OBJC_EXPORT id<HCMatcher> HCWrapInMatcher(id matcherOrValue);
@@ -0,0 +1,24 @@
//
// OCHamcrest - HCWrapInMatcher.m
// Copyright 2012 hamcrest.org. See LICENSE.txt
//
// Created by: Jon Reid, http://qualitycoding.org/
// Docs: http://hamcrest.github.com/OCHamcrest/
// Source: https://github.com/hamcrest/OCHamcrest
//
#import "HCWrapInMatcher.h"
#import "HCIsEqual.h"
id<HCMatcher> HCWrapInMatcher(id matcherOrValue)
{
if (!matcherOrValue)
return nil;
if ([matcherOrValue conformsToProtocol:@protocol(HCMatcher)])
return matcherOrValue;
else
return HC_equalTo(matcherOrValue);
}
@@ -0,0 +1,120 @@
//
// OCHamcrest - CustomMatchers.h
// Copyright 2012 hamcrest.org. See LICENSE.txt
//
// Created by: Jon Reid, http://qualitycoding.org/
// Docs: http://hamcrest.github.com/OCHamcrest/
// Source: https://github.com/hamcrest/OCHamcrest
//
/**
@page custom-matchers Writing custom matchers
OCHamcrest comes bundled with lots of useful matchers, but you'll probably find that you need to
create your own from time to time to fit your testing needs.
This commonly occurs when you find a fragment of code that tests the same set of properties over
and over again (and in different tests), and you want to bundle the fragment into a single assertion.
By writing your own matcher you'll eliminate code duplication and make your tests more readable!
Let's write our own matcher for testing if a calendar date falls on a Saturday. This is the test
we want to write:
@code
- (void)testDateIsOnASaturday
{
NSCalendarDate* date = [NSCalendarDate dateWithString:@"26 Apr 2008" calendarFormat:@"%d %b %Y"];
assertThat(date, is(onASaturday()))
}
@endcode
Here's the interface:
@code
#import <OCHamcrest/HCBaseMatcher.h>
#import <objc/objc-api.h>
@interface IsGivenDayOfWeek : HCBaseMatcher
{
NSInteger day; // Sunday is 0, Saturday is 6
}
+ (id)isGivenDayOfWeek:(NSInteger)dayOfWeek;
- (id)initWithDay:(NSInteger)dayOfWeek;
@end
OBJC_EXPORT id <HCMatcher> onASaturday();
@endcode
The interface consists of two parts: a class definition, and a factory function (with C binding).
Here's what the implementation looks like:
@code
#import "IsGivenDayOfWeek.h"
#import <OCHamcrest/HCDescription.h>
@implementation IsGivenDayOfWeek
+ (id)isGivenDayOfWeek:(NSInteger)dayOfWeek
{
return [[self alloc] initWithDay:dayOfWeek];
}
- (id)initWithDay:(NSInteger)dayOfWeek
{
self = [super init];
if (self != nil)
day = dayOfWeek;
return self;
}
// Test whether item matches.
- (BOOL)matches:(id)item
{
if (![item respondsToSelector:@selector(dayOfWeek)])
return NO;
return [item dayOfWeek] == day;
}
// Describe the matcher.
- (void)describeTo:(id <HCDescription>)description
{
NSString *dayAsString[] =
{ @"Sunday", @"Monday", @"Tuesday", @"Wednesday", @"Thursday", @"Friday", @"Saturday" };
[[description appendText:@"calendar date falling on "] appendText:dayAsString[day]];
}
@end
id <HCMatcher> onASaturday()
{
return [IsGivenDayOfWeek isGivenDayOfWeek:6];
}
@endcode
For our Matcher implementation we implement the @c -matches: method (which calls
@c -dayOfWeek after confirming that the argument has such a method) and the
@c -describe_to: method (which is used to produce a failure message when a test fails).
Here's an example of how the failure message looks:
@code
NSCalendarDate* date = [NSCalendarDate dateWithString: @"6 April 2008"
calendarFormat: @"%d %B %Y"];
assertThat(date, is(onASaturday()));
@endcode
fails with the message
@verbatim Expected: is calendar date falling on Saturday, got: <06 April 2008> @endverbatim
and Xcode shows it as a build error. Clicking the error message takes you to the assertion that
failed.
Even though the @c onASaturday function creates a new matcher each time it is called, you should
not assume this is the only usage pattern for your matcher. Therefore you should make sure your
matcher is stateless, so a single instance can be reused between matches.
*/
@@ -0,0 +1,63 @@
//
// OCHamcrest - HCHasCount.h
// Copyright 2012 hamcrest.org. See LICENSE.txt
//
// Created by: Jon Reid, http://qualitycoding.org/
// Docs: http://hamcrest.github.com/OCHamcrest/
// Source: https://github.com/hamcrest/OCHamcrest
//
#import <OCHamcrest/HCBaseMatcher.h>
@interface HCHasCount : HCBaseMatcher
{
id<HCMatcher> countMatcher;
}
+ (id)hasCount:(id<HCMatcher>)matcher;
- (id)initWithCount:(id<HCMatcher>)matcher;
@end
OBJC_EXPORT id<HCMatcher> HC_hasCount(id<HCMatcher> matcher);
/**
hasCount(aMatcher) -
Matches if object's @c -count satisfies a given matcher.
@param aMatcher The matcher to satisfy.
This matcher invokes @c -count on the evaluated object to get the number of elements it
contains, passing the result to @a aMatcher for evaluation.
(In the event of a name clash, don't \#define @c HC_SHORTHAND and use the synonym
@c HC_hasCount instead.)
@ingroup collection_matchers
*/
#ifdef HC_SHORTHAND
#define hasCount HC_hasCount
#endif
OBJC_EXPORT id<HCMatcher> HC_hasCountOf(NSUInteger count);
/**
hasCountOf(value) -
Matches if object's @c -count equals a given value.
@param value @c NSUInteger value to compare against as the expected value.
This matcher invokes @c -count on the evaluated object to get the number of elements it
contains, comparing the result to @a value for equality.
(In the event of a name clash, don't \#define @c HC_SHORTHAND and use the synonym
@c HC_hasCountOf instead.)
@ingroup collection_matchers
*/
#ifdef HC_SHORTHAND
#define hasCountOf HC_hasCountOf
#endif
@@ -0,0 +1,70 @@
//
// OCHamcrest - HCHasCount.m
// Copyright 2012 hamcrest.org. See LICENSE.txt
//
// Created by: Jon Reid, http://qualitycoding.org/
// Docs: http://hamcrest.github.com/OCHamcrest/
// Source: https://github.com/hamcrest/OCHamcrest
//
#import "HCHasCount.h"
#import "HCDescription.h"
#import "HCIsEqualToNumber.h"
@implementation HCHasCount
+ (id)hasCount:(id<HCMatcher>)matcher
{
return [[self alloc] initWithCount:matcher];
}
- (id)initWithCount:(id<HCMatcher>)matcher
{
self = [super init];
if (self)
countMatcher = matcher;
return self;
}
- (BOOL)matches:(id)item
{
if (![item respondsToSelector:@selector(count)])
return NO;
NSNumber *count = @([item count]);
return [countMatcher matches:count];
}
- (void)describeMismatchOf:(id)item to:(id<HCDescription>)mismatchDescription
{
[mismatchDescription appendText:@"was "];
if ([item respondsToSelector:@selector(count)])
{
[[[mismatchDescription appendText:@"count of "]
appendDescriptionOf:@([item count])]
appendText:@" with "];
}
[mismatchDescription appendDescriptionOf:item];
}
- (void)describeTo:(id<HCDescription>)description
{
[[description appendText:@"a collection with count of "] appendDescriptionOf:countMatcher];
}
@end
#pragma mark -
id<HCMatcher> HC_hasCount(id<HCMatcher> matcher)
{
return [HCHasCount hasCount:matcher];
}
id<HCMatcher> HC_hasCountOf(NSUInteger value)
{
return HC_hasCount(HC_equalToUnsignedInteger(value));
}
@@ -0,0 +1,69 @@
//
// OCHamcrest - HCIsCollectionContaining.h
// Copyright 2012 hamcrest.org. See LICENSE.txt
//
// Created by: Jon Reid, http://qualitycoding.org/
// Docs: http://hamcrest.github.com/OCHamcrest/
// Source: https://github.com/hamcrest/OCHamcrest
//
#import <OCHamcrest/HCBaseMatcher.h>
@interface HCIsCollectionContaining : HCBaseMatcher
{
id<HCMatcher> elementMatcher;
}
+ (id)isCollectionContaining:(id<HCMatcher>)anElementMatcher;
- (id)initWithMatcher:(id<HCMatcher>)anElementMatcher;
@end
OBJC_EXPORT id<HCMatcher> HC_hasItem(id itemMatch);
/**
hasItem(aMatcher) -
Matches if any element of collection satisfies a given matcher.
@param aMatcher The matcher to satisfy, or an expected value for @ref equalTo matching.
This matcher iterates the evaluated collection, searching for any element that satisfies a
given matcher. If a matching element is found, @c hasItem is satisfied.
If the @a aMatcher argument is not a matcher, it is implicitly wrapped in an @ref equalTo
matcher to check for equality.
(In the event of a name clash, don't \#define @c HC_SHORTHAND and use the synonym
@c HC_hasItem instead.)
@ingroup collection_matchers
*/
#ifdef HC_SHORTHAND
#define hasItem HC_hasItem
#endif
OBJC_EXPORT id<HCMatcher> HC_hasItems(id itemMatch, ...) NS_REQUIRES_NIL_TERMINATION;
/**
hasItems(firstMatcher, ...) -
Matches if all of the given matchers are satisfied by any elements of the collection.
@param firstMatcher,... A comma-separated list of matchers ending with @c nil.
This matcher iterates the given matchers, searching for any elements in the evaluated collection
that satisfy them. If each matcher is satisfied, then @c hasItems is satisfied.
Any argument that is not a matcher is implicitly wrapped in an @ref equalTo matcher to check for
equality.
(In the event of a name clash, don't \#define @c HC_SHORTHAND and use the synonym
@c hasItems instead.)
@ingroup collection_matchers
*/
#ifdef HC_SHORTHAND
#define hasItems HC_hasItems
#endif
@@ -0,0 +1,76 @@
//
// OCHamcrest - HCIsCollectionContaining.m
// Copyright 2012 hamcrest.org. See LICENSE.txt
//
// Created by: Jon Reid, http://qualitycoding.org/
// Docs: http://hamcrest.github.com/OCHamcrest/
// Source: https://github.com/hamcrest/OCHamcrest
//
#import "HCIsCollectionContaining.h"
#import "HCAllOf.h"
#import "HCDescription.h"
#import "HCRequireNonNilObject.h"
#import "HCWrapInMatcher.h"
@implementation HCIsCollectionContaining
+ (id)isCollectionContaining:(id<HCMatcher>)anElementMatcher
{
return [[self alloc] initWithMatcher:anElementMatcher];
}
- (id)initWithMatcher:(id<HCMatcher>)anElementMatcher
{
self = [super init];
if (self)
elementMatcher = anElementMatcher;
return self;
}
- (BOOL)matches:(id)collection
{
if (![collection conformsToProtocol:@protocol(NSFastEnumeration)])
return NO;
for (id item in collection)
if ([elementMatcher matches:item])
return YES;
return NO;
}
- (void)describeTo:(id<HCDescription>)description
{
[[description appendText:@"a collection containing "]
appendDescriptionOf:elementMatcher];
}
@end
#pragma mark -
id<HCMatcher> HC_hasItem(id itemMatch)
{
HCRequireNonNilObject(itemMatch);
return [HCIsCollectionContaining isCollectionContaining:HCWrapInMatcher(itemMatch)];
}
id<HCMatcher> HC_hasItems(id itemMatch, ...)
{
NSMutableArray *matchers = [NSMutableArray arrayWithObject:HC_hasItem(itemMatch)];
va_list args;
va_start(args, itemMatch);
itemMatch = va_arg(args, id);
while (itemMatch != nil)
{
[matchers addObject:HC_hasItem(itemMatch)];
itemMatch = va_arg(args, id);
}
va_end(args);
return [HCAllOf allOf:matchers];
}
@@ -0,0 +1,47 @@
//
// OCHamcrest - HCIsCollectionContainingInAnyOrder.h
// Copyright 2012 hamcrest.org. See LICENSE.txt
//
// Created by: Jon Reid, http://qualitycoding.org/
// Docs: http://hamcrest.github.com/OCHamcrest/
// Source: https://github.com/hamcrest/OCHamcrest
//
#import <OCHamcrest/HCBaseMatcher.h>
@interface HCIsCollectionContainingInAnyOrder : HCBaseMatcher
{
NSMutableArray *matchers;
}
+ (id)isCollectionContainingInAnyOrder:(NSMutableArray *)itemMatchers;
- (id)initWithMatchers:(NSMutableArray *)itemMatchers;
@end
OBJC_EXPORT id<HCMatcher> HC_containsInAnyOrder(id itemMatch, ...) NS_REQUIRES_NIL_TERMINATION;
/**
containsInAnyOrder(firstMatcher, ...) -
Matches if collection's elements, in any order, satisfy a given list of matchers.
@param firstMatcher,... A comma-separated list of matchers ending with @c nil.
This matcher iterates the evaluated collection, seeing if each element satisfies any of the
given matchers. The matchers are tried from left to right, and when a satisfied matcher is
found, it is no longer a candidate for the remaining elements. If a one-to-one correspondence is
established between elements and matchers, @c containsInAnyOrder is satisfied.
Any argument that is not a matcher is implicitly wrapped in an @ref equalTo matcher to check for
equality.
(In the event of a name clash, don't \#define @c HC_SHORTHAND and use the synonym
@c HC_containsInAnyOrder instead.)
@ingroup collection_matchers
*/
#ifdef HC_SHORTHAND
#define containsInAnyOrder HC_containsInAnyOrder
#endif
@@ -0,0 +1,142 @@
//
// OCHamcrest - HCIsCollectionContainingInAnyOrder.m
// Copyright 2012 hamcrest.org. See LICENSE.txt
//
// Created by: Jon Reid, http://qualitycoding.org/
// Docs: http://hamcrest.github.com/OCHamcrest/
// Source: https://github.com/hamcrest/OCHamcrest
//
#import "HCIsCollectionContainingInAnyOrder.h"
#import "HCAllOf.h"
#import "HCDescription.h"
#import "HCWrapInMatcher.h"
@interface HCMatchingInAnyOrder : NSObject
{
NSMutableArray *matchers;
id<HCDescription, NSObject> mismatchDescription;
}
@end
@implementation HCMatchingInAnyOrder
- (id)initWithMatchers:(NSMutableArray *)itemMatchers
mismatchDescription:(id<HCDescription, NSObject>)description
{
self = [super init];
if (self)
{
matchers = itemMatchers;
mismatchDescription = description;
}
return self;
}
- (BOOL)matches:(id)item
{
NSUInteger index = 0;
for (id<HCMatcher> matcher in matchers)
{
if ([matcher matches:item])
{
[matchers removeObjectAtIndex:index];
return YES;
}
++index;
}
[[mismatchDescription appendText:@"not matched: "] appendDescriptionOf:item];
return NO;
}
- (BOOL)isFinishedWith:(NSArray *)collection
{
if ([matchers count] == 0)
return YES;
[[[[mismatchDescription appendText:@"no item matches: "]
appendList:matchers start:@"" separator:@", " end:@""]
appendText:@" in "]
appendList:collection start:@"[" separator:@", " end:@"]"];
return NO;
}
@end
#pragma mark -
@implementation HCIsCollectionContainingInAnyOrder
+ (id)isCollectionContainingInAnyOrder:(NSMutableArray *)itemMatchers
{
return [[self alloc] initWithMatchers:itemMatchers];
}
- (id)initWithMatchers:(NSMutableArray *)itemMatchers
{
self = [super init];
if (self)
matchers = itemMatchers;
return self;
}
- (BOOL)matches:(id)collection
{
return [self matches:collection describingMismatchTo:nil];
}
- (BOOL)matches:(id)collection describingMismatchTo:(id<HCDescription>)mismatchDescription
{
if (![collection conformsToProtocol:@protocol(NSFastEnumeration)])
{
[super describeMismatchOf:collection to:mismatchDescription];
return NO;
}
HCMatchingInAnyOrder *matchSequence =
[[HCMatchingInAnyOrder alloc] initWithMatchers:matchers
mismatchDescription:mismatchDescription];
for (id item in collection)
if (![matchSequence matches:item])
return NO;
return [matchSequence isFinishedWith:collection];
}
- (void)describeMismatchOf:(id)item to:(id<HCDescription>)mismatchDescription
{
[self matches:item describingMismatchTo:mismatchDescription];
}
- (void)describeTo:(id<HCDescription>)description
{
[[[description appendText:@"a collection over "]
appendList:matchers start:@"[" separator:@", " end:@"]"]
appendText:@" in any order"];
}
@end
#pragma mark -
id<HCMatcher> HC_containsInAnyOrder(id itemMatch, ...)
{
NSMutableArray *matchers = [NSMutableArray arrayWithObject:HCWrapInMatcher(itemMatch)];
va_list args;
va_start(args, itemMatch);
itemMatch = va_arg(args, id);
while (itemMatch != nil)
{
[matchers addObject:HCWrapInMatcher(itemMatch)];
itemMatch = va_arg(args, id);
}
va_end(args);
return [HCIsCollectionContainingInAnyOrder isCollectionContainingInAnyOrder:matchers];
}
@@ -0,0 +1,45 @@
//
// OCHamcrest - HCIsCollectionContainingInOrder.h
// Copyright 2012 hamcrest.org. See LICENSE.txt
//
// Created by: Jon Reid, http://qualitycoding.org/
// Docs: http://hamcrest.github.com/OCHamcrest/
// Source: https://github.com/hamcrest/OCHamcrest
//
#import <OCHamcrest/HCBaseMatcher.h>
@interface HCIsCollectionContainingInOrder : HCBaseMatcher
{
NSArray *matchers;
}
+ (id)isCollectionContainingInOrder:(NSArray *)itemMatchers;
- (id)initWithMatchers:(NSArray *)itemMatchers;
@end
OBJC_EXPORT id<HCMatcher> HC_contains(id itemMatch, ...) NS_REQUIRES_NIL_TERMINATION;
/**
contains(firstMatcher, ...) -
Matches if collection's elements satisfy a given list of matchers, in order.
@param firstMatcher,... A comma-separated list of matchers ending with @c nil.
This matcher iterates the evaluated collection and a given list of matchers, seeing if each
element satisfies its corresponding matcher.
Any argument that is not a matcher is implicitly wrapped in an @ref equalTo matcher to check for
equality.
(In the event of a name clash, don't \#define @c HC_SHORTHAND and use the synonym
@c HC_contains instead.)
@ingroup collection_matchers
*/
#ifdef HC_SHORTHAND
#define contains HC_contains
#endif
@@ -0,0 +1,161 @@
//
// OCHamcrest - HCIsCollectionContainingInOrder.m
// Copyright 2012 hamcrest.org. See LICENSE.txt
//
// Created by: Jon Reid, http://qualitycoding.org/
// Docs: http://hamcrest.github.com/OCHamcrest/
// Source: https://github.com/hamcrest/OCHamcrest
//
#import "HCIsCollectionContainingInOrder.h"
#import "HCAllOf.h"
#import "HCDescription.h"
#import "HCWrapInMatcher.h"
@interface HCMatchSequence : NSObject
{
NSArray *matchers;
id<HCDescription, NSObject> mismatchDescription;
NSUInteger nextMatchIndex;
}
- (BOOL)isMatched:(id)item;
- (BOOL)isNotSurplus:(id)item;
- (void)describeMismatchOfMatcher:(id<HCMatcher>)matcher item:(id)item;
@end
@implementation HCMatchSequence
- (id)initWithMatchers:(NSArray *)itemMatchers mismatchDescription:(id<HCDescription, NSObject>)description
{
self = [super init];
if (self)
{
matchers = itemMatchers;
mismatchDescription = description;
}
return self;
}
- (BOOL)matches:(id)item
{
return [self isNotSurplus:item] && [self isMatched:item];
}
- (BOOL)isFinished
{
if (nextMatchIndex < [matchers count])
{
[[mismatchDescription appendText:@"no item matched: "]
appendDescriptionOf:matchers[nextMatchIndex]];
return NO;
}
return YES;
}
- (BOOL)isMatched:(id)item
{
id<HCMatcher> matcher = matchers[nextMatchIndex];
if (![matcher matches:item])
{
[self describeMismatchOfMatcher:matcher item:item];
return NO;
}
++nextMatchIndex;
return YES;
}
- (BOOL)isNotSurplus:(id)item
{
if ([matchers count] <= nextMatchIndex)
{
[[mismatchDescription appendText:@"not matched: "] appendDescriptionOf:item];
return NO;
}
return YES;
}
- (void)describeMismatchOfMatcher:(id<HCMatcher>)matcher item:(id)item
{
[mismatchDescription appendText:[NSString stringWithFormat:@"item %zi: ", nextMatchIndex]];
[matcher describeMismatchOf:item to:mismatchDescription];
}
@end
#pragma mark -
@implementation HCIsCollectionContainingInOrder
+ (id)isCollectionContainingInOrder:(NSArray *)itemMatchers
{
return [[self alloc] initWithMatchers:itemMatchers];
}
- (id)initWithMatchers:(NSArray *)itemMatchers
{
self = [super init];
if (self)
matchers = itemMatchers;
return self;
}
- (BOOL)matches:(id)collection
{
return [self matches:collection describingMismatchTo:nil];
}
- (BOOL)matches:(id)collection describingMismatchTo:(id<HCDescription, NSObject>)mismatchDescription
{
if (![collection conformsToProtocol:@protocol(NSFastEnumeration)])
{
[super describeMismatchOf:collection to:mismatchDescription];
return NO;
}
HCMatchSequence *matchSequence =
[[HCMatchSequence alloc] initWithMatchers:matchers
mismatchDescription:mismatchDescription];
for (id item in collection)
if (![matchSequence matches:item])
return NO;
return [matchSequence isFinished];
}
- (void)describeMismatchOf:(id)item to:(id<HCDescription>)mismatchDescription
{
[self matches:item describingMismatchTo:mismatchDescription];
}
- (void)describeTo:(id<HCDescription>)description
{
[[description appendText:@"a collection containing "]
appendList:matchers start:@"[" separator:@", " end:@"]"];
}
@end
#pragma mark -
id<HCMatcher> HC_contains(id itemMatch, ...)
{
NSMutableArray *matchers = [NSMutableArray arrayWithObject:HCWrapInMatcher(itemMatch)];
va_list args;
va_start(args, itemMatch);
itemMatch = va_arg(args, id);
while (itemMatch != nil)
{
[matchers addObject:HCWrapInMatcher(itemMatch)];
itemMatch = va_arg(args, id);
}
va_end(args);
return [HCIsCollectionContainingInOrder isCollectionContainingInOrder:matchers];
}
@@ -0,0 +1,52 @@
//
// OCHamcrest - HCIsCollectionOnlyContaining.h
// Copyright 2012 hamcrest.org. See LICENSE.txt
//
// Created by: Jon Reid, http://qualitycoding.org/
// Docs: http://hamcrest.github.com/OCHamcrest/
// Source: https://github.com/hamcrest/OCHamcrest
//
#import <OCHamcrest/HCBaseMatcher.h>
@interface HCIsCollectionOnlyContaining : HCBaseMatcher
{
id<HCMatcher> matcher;
}
+ (id)isCollectionOnlyContaining:(id<HCMatcher>)aMatcher;
- (id)initWithMatcher:(id<HCMatcher>)aMatcher;
@end
OBJC_EXPORT id<HCMatcher> HC_onlyContains(id itemMatch, ...) NS_REQUIRES_NIL_TERMINATION;
/**
onlyContains(firstMatcher, ...) -
Matches if each element of collection satisfies any of the given matchers.
@param firstMatcher,... A comma-separated list of matchers ending with @c nil.
This matcher iterates the evaluated collection, confirming whether each element satisfies any of
the given matchers.
Any argument that is not a matcher is implicitly wrapped in an @ref equalTo matcher to check for
equality.
Example:
@par
@ref onlyContains(startsWith(@"Jo"), nil)
will match a collection [@"Jon", @"John", @"Johann"].
(In the event of a name clash, don't \#define @c HC_SHORTHAND and use the synonym
@c HC_onlyContains instead.)
@ingroup collection_matchers
*/
#ifdef HC_SHORTHAND
#define onlyContains HC_onlyContains
#endif
@@ -0,0 +1,72 @@
//
// OCHamcrest - HCIsCollectionOnlyContaining.m
// Copyright 2012 hamcrest.org. See LICENSE.txt
//
// Created by: Jon Reid, http://qualitycoding.org/
// Docs: http://hamcrest.github.com/OCHamcrest/
// Source: https://github.com/hamcrest/OCHamcrest
//
#import "HCIsCollectionOnlyContaining.h"
#import "HCAnyOf.h"
#import "HCDescription.h"
#import "HCWrapInMatcher.h"
@implementation HCIsCollectionOnlyContaining
+ (id)isCollectionOnlyContaining:(id<HCMatcher>)aMatcher
{
return [[self alloc] initWithMatcher:aMatcher];
}
- (id)initWithMatcher:(id<HCMatcher>)aMatcher
{
self = [super init];
if (self)
matcher = aMatcher;
return self;
}
- (BOOL)matches:(id)collection
{
if (![collection conformsToProtocol:@protocol(NSFastEnumeration)])
return NO;
if ([collection count] == 0)
return NO;
for (id item in collection)
if (![matcher matches:item])
return NO;
return YES;
}
- (void)describeTo:(id<HCDescription>)description
{
[[description appendText:@"a collection containing items matching "]
appendDescriptionOf:matcher];
}
@end
#pragma mark -
id<HCMatcher> HC_onlyContains(id itemMatch, ...)
{
NSMutableArray *matchers = [NSMutableArray arrayWithObject:HCWrapInMatcher(itemMatch)];
va_list args;
va_start(args, itemMatch);
itemMatch = va_arg(args, id);
while (itemMatch != nil)
{
[matchers addObject:HCWrapInMatcher(itemMatch)];
itemMatch = va_arg(args, id);
}
va_end(args);
return [HCIsCollectionOnlyContaining isCollectionOnlyContaining:[HCAnyOf anyOf:matchers]];
}
@@ -0,0 +1,54 @@
//
// OCHamcrest - HCIsDictionaryContaining.h
// Copyright 2012 hamcrest.org. See LICENSE.txt
//
// Created by: Jon Reid, http://qualitycoding.org/
// Docs: http://hamcrest.github.com/OCHamcrest/
// Source: https://github.com/hamcrest/OCHamcrest
//
#import <OCHamcrest/HCBaseMatcher.h>
@interface HCIsDictionaryContaining : HCBaseMatcher
{
id<HCMatcher> keyMatcher;
id<HCMatcher> valueMatcher;
}
+ (id)isDictionaryContainingKey:(id<HCMatcher>)aKeyMatcher
value:(id<HCMatcher>)aValueMatcher;
- (id)initWithKeyMatcher:(id<HCMatcher>)aKeyMatcher
valueMatcher:(id<HCMatcher>)aValueMatcher;
@end
OBJC_EXPORT id<HCMatcher> HC_hasEntry(id keyMatch, id valueMatch);
/**
hasEntry(keyMatcher, valueMatcher) -
Matches if dictionary contains key-value entry satisfying a given pair of matchers.
@param keyMatcher The matcher to satisfy for the key, or an expected value for @ref equalTo matching.
@param valueMatcher The matcher to satisfy for the value, or an expected value for @ref equalTo matching.
This matcher iterates the evaluated dictionary, searching for any key-value entry that satisfies
@a keyMatcher and @a valueMatcher. If a matching entry is found, @c hasEntry is satisfied.
Any argument that is not a matcher is implicitly wrapped in an @ref equalTo matcher to check for
equality.
Examples:
@li @ref hasEntry(@ref equalTo(@"foo"), equalTo(@"bar"))
@li @ref hasEntry(@"foo", @"bar")
(In the event of a name clash, don't \#define @c HC_SHORTHAND and use the synonym
@c HC_hasEntry instead.)
@ingroup collection_matchers
*/
#ifdef HC_SHORTHAND
#define hasEntry HC_hasEntry
#endif
@@ -0,0 +1,66 @@
//
// OCHamcrest - HCIsDictionaryContaining.m
// Copyright 2012 hamcrest.org. See LICENSE.txt
//
// Created by: Jon Reid, http://qualitycoding.org/
// Docs: http://hamcrest.github.com/OCHamcrest/
// Source: https://github.com/hamcrest/OCHamcrest
//
#import "HCIsDictionaryContaining.h"
#import "HCDescription.h"
#import "HCRequireNonNilObject.h"
#import "HCWrapInMatcher.h"
@implementation HCIsDictionaryContaining
+ (id)isDictionaryContainingKey:(id<HCMatcher>)aKeyMatcher
value:(id<HCMatcher>)aValueMatcher
{
return [[self alloc] initWithKeyMatcher:aKeyMatcher valueMatcher:aValueMatcher];
}
- (id)initWithKeyMatcher:(id<HCMatcher>)aKeyMatcher
valueMatcher:(id<HCMatcher>)aValueMatcher
{
self = [super init];
if (self)
{
keyMatcher = aKeyMatcher;
valueMatcher = aValueMatcher;
}
return self;
}
- (BOOL)matches:(id)dict
{
if ([dict isKindOfClass:[NSDictionary class]])
for (id oneKey in dict)
if ([keyMatcher matches:oneKey] && [valueMatcher matches:dict[oneKey]])
return YES;
return NO;
}
- (void)describeTo:(id<HCDescription>)description
{
[[[[[description appendText:@"a dictionary containing { "]
appendDescriptionOf:keyMatcher]
appendText:@" = "]
appendDescriptionOf:valueMatcher]
appendText:@"; }"];
}
@end
#pragma mark -
id<HCMatcher> HC_hasEntry(id keyMatch, id valueMatch)
{
HCRequireNonNilObject(keyMatch);
HCRequireNonNilObject(valueMatch);
return [HCIsDictionaryContaining isDictionaryContainingKey:HCWrapInMatcher(keyMatch)
value:HCWrapInMatcher(valueMatch)];
}
@@ -0,0 +1,53 @@
//
// OCHamcrest - HCIsDictionaryContainingEntries.h
// Copyright 2012 hamcrest.org. See LICENSE.txt
//
// Created by: Jon Reid, http://qualitycoding.org/
// Docs: http://hamcrest.github.com/OCHamcrest/
// Source: https://github.com/hamcrest/OCHamcrest
//
#import <OCHamcrest/HCBaseMatcher.h>
@interface HCIsDictionaryContainingEntries : HCBaseMatcher
{
NSArray *keys;
NSArray *valueMatchers;
}
+ (id)isDictionaryContainingKeys:(NSArray *)theKeys
valueMatchers:(NSArray *)theValueMatchers;
- (id)initWithKeys:(NSArray *)theKeys
valueMatchers:(NSArray *)theValueMatchers;
@end
OBJC_EXPORT id<HCMatcher> HC_hasEntries(id keysAndValueMatch, ...) NS_REQUIRES_NIL_TERMINATION;
/**
hasEntries(firstKey, valueMatcher, ...) -
Matches if dictionary contains entries satisfying a list of alternating keys and their value
matchers.
@param firstKey A key (not a matcher) to look up.
@param valueMatcher,... The matcher to satisfy for the value, or an expected value for @ref equalTo matching.
Note that the keys must be actual keys, not matchers. Any value argument that is not a matcher
is implicitly wrapped in an @ref equalTo matcher to check for equality. The list must end with
@c nil.
Examples:
@li @ref hasEntries(@"first", equalTo(@"Jon"), @"last", equalTo(@"Reid"), nil)
@li @ref hasEntries(@"first", @"Jon", @"last", @"Reid", nil)
(In the event of a name clash, don't \#define @c HC_SHORTHAND and use the synonym
@c HC_hasEntry instead.)
@ingroup collection_matchers
*/
#ifdef HC_SHORTHAND
#define hasEntries HC_hasEntries
#endif
@@ -0,0 +1,141 @@
//
// OCHamcrest - HCIsDictionaryContainingEntries.m
// Copyright 2012 hamcrest.org. See LICENSE.txt
//
// Created by: Jon Reid, http://qualitycoding.org/
// Docs: http://hamcrest.github.com/OCHamcrest/
// Source: https://github.com/hamcrest/OCHamcrest
//
#import "HCIsDictionaryContainingEntries.h"
#import "HCDescription.h"
#import "HCWrapInMatcher.h"
@implementation HCIsDictionaryContainingEntries
+ (id)isDictionaryContainingKeys:(NSArray *)theKeys
valueMatchers:(NSArray *)theValueMatchers
{
return [[self alloc] initWithKeys:theKeys valueMatchers:theValueMatchers];
}
- (id)initWithKeys:(NSArray *)theKeys
valueMatchers:(NSArray *)theValueMatchers
{
self = [super init];
if (self)
{
keys = theKeys;
valueMatchers = theValueMatchers;
}
return self;
}
- (BOOL)matches:(id)item
{
return [self matches:item describingMismatchTo:nil];
}
- (BOOL)matches:(id)dict describingMismatchTo:(id<HCDescription>)mismatchDescription
{
if (![dict isKindOfClass:[NSDictionary class]])
{
[super describeMismatchOf:dict to:mismatchDescription];
return NO;
}
NSUInteger count = [keys count];
for (NSUInteger index = 0; index < count; ++index)
{
id key = keys[index];
if (dict[key] == nil)
{
[[[[mismatchDescription appendText:@"no "]
appendDescriptionOf:key]
appendText:@" key in "]
appendDescriptionOf:dict];
return NO;
}
id valueMatcher = valueMatchers[index];
id actualValue = dict[key];
if (![valueMatcher matches:actualValue])
{
[[[[mismatchDescription appendText:@"value for "]
appendDescriptionOf:key]
appendText:@" was "]
appendDescriptionOf:actualValue];
return NO;
}
}
return YES;
}
- (void)describeMismatchOf:(id)item to:(id<HCDescription>)mismatchDescription
{
[self matches:item describingMismatchTo:mismatchDescription];
}
- (void)describeKeyValueAtIndex:(NSUInteger)index to:(id<HCDescription>)description
{
[[[[description appendDescriptionOf:keys[index]]
appendText:@" = "]
appendDescriptionOf:valueMatchers[index]]
appendText:@"; "];
}
- (void)describeTo:(id<HCDescription>)description
{
[description appendText:@"a dictionary containing { "];
NSUInteger count = [keys count];
NSUInteger index = 0;
for (; index < count - 1; ++index)
[self describeKeyValueAtIndex:index to:description];
[self describeKeyValueAtIndex:index to:description];
[description appendText:@"}"];
}
@end
#pragma mark -
static void requirePairedObject(id obj)
{
if (obj == nil)
{
@throw [NSException exceptionWithName:@"NilObject"
reason:@"HC_hasEntries keys and value matchers must be paired"
userInfo:nil];
}
}
id<HCMatcher> HC_hasEntries(id keysAndValueMatch, ...)
{
va_list args;
va_start(args, keysAndValueMatch);
id key = keysAndValueMatch;
id valueMatcher = va_arg(args, id);
requirePairedObject(valueMatcher);
NSMutableArray *keys = [NSMutableArray arrayWithObject:key];
NSMutableArray *valueMatchers = [NSMutableArray arrayWithObject:HCWrapInMatcher(valueMatcher)];
key = va_arg(args, id);
while (key != nil)
{
[keys addObject:key];
valueMatcher = va_arg(args, id);
requirePairedObject(valueMatcher);
[valueMatchers addObject:HCWrapInMatcher(valueMatcher)];
key = va_arg(args, id);
}
return [HCIsDictionaryContainingEntries isDictionaryContainingKeys:keys
valueMatchers:valueMatchers];
}
@@ -0,0 +1,49 @@
//
// OCHamcrest - HCIsDictionaryContainingKey.h
// Copyright 2012 hamcrest.org. See LICENSE.txt
//
// Created by: Jon Reid, http://qualitycoding.org/
// Docs: http://hamcrest.github.com/OCHamcrest/
// Source: https://github.com/hamcrest/OCHamcrest
//
#import <OCHamcrest/HCBaseMatcher.h>
@interface HCIsDictionaryContainingKey : HCBaseMatcher
{
id<HCMatcher> keyMatcher;
}
+ (id)isDictionaryContainingKey:(id<HCMatcher>)theKeyMatcher;
- (id)initWithKeyMatcher:(id<HCMatcher>)theKeyMatcher;
@end
OBJC_EXPORT id<HCMatcher> HC_hasKey(id keyMatch);
/**
hasKey(keyMatcher) -
Matches if dictionary contains an entry whose key satisfies a given matcher.
@param keyMatcher The matcher to satisfy for the key, or an expected value for @ref equalTo matching.
This matcher iterates the evaluated dictionary, searching for any key-value entry whose key
satisfies the given matcher. If a matching entry is found, @c hasKey is satisfied.
Any argument that is not a matcher is implicitly wrapped in an @ref equalTo matcher to check for
equality.
(In the event of a name clash, don't \#define @c HC_SHORTHAND and use the synonym
@c HC_hasKey instead.)
Examples:
@li @ref hasEntry(equalTo(@"foo"))
@li @ref hasEntry(@"foo")
@ingroup collection_matchers
*/
#ifdef HC_SHORTHAND
#define hasKey HC_hasKey
#endif
@@ -0,0 +1,56 @@
//
// OCHamcrest - HCIsDictionaryContainingKey.m
// Copyright 2012 hamcrest.org. See LICENSE.txt
//
// Created by: Jon Reid, http://qualitycoding.org/
// Docs: http://hamcrest.github.com/OCHamcrest/
// Source: https://github.com/hamcrest/OCHamcrest
//
#import "HCIsDictionaryContainingKey.h"
#import "HCDescription.h"
#import "HCRequireNonNilObject.h"
#import "HCWrapInMatcher.h"
@implementation HCIsDictionaryContainingKey
+ (id)isDictionaryContainingKey:(id<HCMatcher>)theKeyMatcher
{
return [[self alloc] initWithKeyMatcher:theKeyMatcher];
}
- (id)initWithKeyMatcher:(id<HCMatcher>)theKeyMatcher
{
self = [super init];
if (self)
keyMatcher = theKeyMatcher;
return self;
}
- (BOOL)matches:(id)dict
{
if ([dict isKindOfClass:[NSDictionary class]])
for (id oneKey in dict)
if ([keyMatcher matches:oneKey])
return YES;
return NO;
}
- (void)describeTo:(id<HCDescription>)description
{
[[description appendText:@"a dictionary containing key "]
appendDescriptionOf:keyMatcher];
}
@end
#pragma mark -
id<HCMatcher> HC_hasKey(id keyMatch)
{
HCRequireNonNilObject(keyMatch);
return [HCIsDictionaryContainingKey isDictionaryContainingKey:HCWrapInMatcher(keyMatch)];
}
@@ -0,0 +1,49 @@
//
// OCHamcrest - HCIsDictionaryContainingValue.h
// Copyright 2012 hamcrest.org. See LICENSE.txt
//
// Created by: Jon Reid, http://qualitycoding.org/
// Docs: http://hamcrest.github.com/OCHamcrest/
// Source: https://github.com/hamcrest/OCHamcrest
//
#import <OCHamcrest/HCBaseMatcher.h>
@interface HCIsDictionaryContainingValue : HCBaseMatcher
{
id<HCMatcher> valueMatcher;
}
+ (id)isDictionaryContainingValue:(id<HCMatcher>)theValueMatcher;
- (id)initWithValueMatcher:(id<HCMatcher>)theValueMatcher;
@end
OBJC_EXPORT id<HCMatcher> HC_hasValue(id valueMatch);
/**
hasValue(valueMatcher) -
Matches if dictionary contains an entry whose value satisfies a given matcher.
@param valueMatcher The matcher to satisfy for the value, or an expected value for @ref equalTo matching.
This matcher iterates the evaluated dictionary, searching for any key-value entry whose value
satisfies the given matcher. If a matching entry is found, @c hasValue is satisfied.
Any argument that is not a matcher is implicitly wrapped in an @ref equalTo matcher to check for
equality.
Examples:
@li @ref hasValue(equalTo(@"bar"))
@li @ref hasValue(@"bar")
(In the event of a name clash, don't \#define @c HC_SHORTHAND and use the synonym
@c HC_hasValue instead.)
@ingroup collection_matchers
*/
#ifdef HC_SHORTHAND
#define hasValue HC_hasValue
#endif
@@ -0,0 +1,56 @@
//
// OCHamcrest - HCIsDictionaryContainingValue.m
// Copyright 2012 hamcrest.org. See LICENSE.txt
//
// Created by: Jon Reid, http://qualitycoding.org/
// Docs: http://hamcrest.github.com/OCHamcrest/
// Source: https://github.com/hamcrest/OCHamcrest
//
#import "HCIsDictionaryContainingValue.h"
#import "HCDescription.h"
#import "HCRequireNonNilObject.h"
#import "HCWrapInMatcher.h"
@implementation HCIsDictionaryContainingValue
+ (id)isDictionaryContainingValue:(id<HCMatcher>)theValueMatcher
{
return [[self alloc] initWithValueMatcher:theValueMatcher];
}
- (id)initWithValueMatcher:(id<HCMatcher>)theValueMatcher
{
self = [super init];
if (self)
valueMatcher = theValueMatcher;
return self;
}
- (BOOL)matches:(id)dict
{
if ([dict respondsToSelector:@selector(allValues)])
for (id oneValue in [dict allValues])
if ([valueMatcher matches:oneValue])
return YES;
return NO;
}
- (void)describeTo:(id<HCDescription>)description
{
[[description appendText:@"a dictionary containing value "]
appendDescriptionOf:valueMatcher];
}
@end
#pragma mark -
id<HCMatcher> HC_hasValue(id valueMatch)
{
HCRequireNonNilObject(valueMatch);
return [HCIsDictionaryContainingValue isDictionaryContainingValue:HCWrapInMatcher(valueMatch)];
}
@@ -0,0 +1,36 @@
//
// OCHamcrest - HCIsEmptyCollection.h
// Copyright 2012 hamcrest.org. See LICENSE.txt
//
// Created by: Jon Reid, http://qualitycoding.org/
// Docs: http://hamcrest.github.com/OCHamcrest/
// Source: https://github.com/hamcrest/OCHamcrest
//
#import <OCHamcrest/HCHasCount.h>
@interface HCIsEmptyCollection : HCHasCount
+ (id)isEmptyCollection;
- (id)init;
@end
OBJC_EXPORT id<HCMatcher> HC_empty(void);
/**
Matches empty collection.
This matcher invokes @c -count on the evaluated object to determine if the number of elements it
contains is zero.
(In the event of a name clash, don't \#define @c HC_SHORTHAND and use the synonym
@c HC_empty instead.)
@ingroup collection_matchers
*/
#ifdef HC_SHORTHAND
#define empty() HC_empty()
#endif
@@ -0,0 +1,47 @@
//
// OCHamcrest - HCIsEmptyCollection.m
// Copyright 2012 hamcrest.org. See LICENSE.txt
//
// Created by: Jon Reid, http://qualitycoding.org/
// Docs: http://hamcrest.github.com/OCHamcrest/
// Source: https://github.com/hamcrest/OCHamcrest
//
#import "HCIsEmptyCollection.h"
#import "HCDescription.h"
#import "HCIsEqualToNumber.h"
@implementation HCIsEmptyCollection
+ (id)isEmptyCollection
{
return [[self alloc] init];
}
- (id)init
{
self = [super initWithCount:HC_equalToUnsignedInteger(0)];
return self;
}
- (void)describeMismatchOf:(id)item to:(id<HCDescription>)mismatchDescription
{
[[mismatchDescription appendText:@"was "] appendDescriptionOf:item];
}
- (void)describeTo:(id<HCDescription>)description
{
[description appendText:@"empty collection"];
}
@end
#pragma mark -
OBJC_EXPORT id<HCMatcher> HC_empty()
{
return [HCIsEmptyCollection isEmptyCollection];
}
@@ -0,0 +1,42 @@
//
// OCHamcrest - HCIsIn.h
// Copyright 2012 hamcrest.org. See LICENSE.txt
//
// Created by: Jon Reid, http://qualitycoding.org/
// Docs: http://hamcrest.github.com/OCHamcrest/
// Source: https://github.com/hamcrest/OCHamcrest
//
#import <OCHamcrest/HCBaseMatcher.h>
@interface HCIsIn : HCBaseMatcher
{
id collection;
}
+ (id)isInCollection:(id)aCollection;
- (id)initWithCollection:(id)aCollection;
@end
OBJC_EXPORT id<HCMatcher> HC_isIn(id aCollection);
/**
isIn(aCollection) -
Matches if evaluated object is present in a given collection.
@param aCollection The collection to search.
This matcher invokes @c -containsObject: on @a aCollection to determine if the evaluated object
is an element of the collection.
(In the event of a name clash, don't \#define @c HC_SHORTHAND and use the synonym
@c HC_isIn instead.)
@ingroup collection_matchers
*/
#ifdef HC_SHORTHAND
#define isIn HC_isIn
#endif
@@ -0,0 +1,56 @@
//
// OCHamcrest - HCIsIn.m
// Copyright 2012 hamcrest.org. See LICENSE.txt
//
// Created by: Jon Reid, http://qualitycoding.org/
// Docs: http://hamcrest.github.com/OCHamcrest/
// Source: https://github.com/hamcrest/OCHamcrest
//
#import "HCIsIn.h"
#import "HCDescription.h"
@implementation HCIsIn
+ (id)isInCollection:(id)aCollection
{
return [[self alloc] initWithCollection:aCollection];
}
- (id)initWithCollection:(id)aCollection
{
if (![aCollection respondsToSelector:@selector(containsObject:)])
{
@throw [NSException exceptionWithName:@"NotAContainer"
reason:@"Object must respond to -containsObject:"
userInfo:nil];
}
self = [super init];
if (self)
collection = aCollection;
return self;
}
- (BOOL)matches:(id)item
{
return [collection containsObject:item];
}
- (void)describeTo:(id<HCDescription>)description
{
[description appendText:@"one of "];
[description appendList:collection start:@"{" separator:@", " end:@"}"];
}
@end
#pragma mark -
id<HCMatcher> HC_isIn(id aCollection)
{
return [HCIsIn isInCollection:aCollection];
}
@@ -0,0 +1,50 @@
//
// OCHamcrest - HCDescribedAs.h
// Copyright 2012 hamcrest.org. See LICENSE.txt
//
// Created by: Jon Reid, http://qualitycoding.org/
// Docs: http://hamcrest.github.com/OCHamcrest/
// Source: https://github.com/hamcrest/OCHamcrest
//
#import <OCHamcrest/HCBaseMatcher.h>
@interface HCDescribedAs : HCBaseMatcher
{
NSString *descriptionTemplate;
id<HCMatcher> matcher;
NSArray *values;
}
+ (id)describedAs:(NSString *)description
forMatcher:(id<HCMatcher>)aMatcher
overValues:(NSArray *)templateValues;
- (id)initWithDescription:(NSString *)description
forMatcher:(id<HCMatcher>)aMatcher
overValues:(NSArray *)templateValues;
@end
OBJC_EXPORT id<HCMatcher> HC_describedAs(NSString *description, id<HCMatcher> matcher, ...) NS_REQUIRES_NIL_TERMINATION;
/**
describedAs(description, matcher, ...) -
Adds custom failure description to a given matcher.
@param description Overrides the matcher's description.
@param matcher,... The matcher to satisfy, followed by a comma-separated list of substitution values ending with @c nil.
The description may contain substitution placeholders \%0, \%1, etc. These will be replaced by
any values that follow the matcher.
(In the event of a name clash, don't \#define @c HC_SHORTHAND and use the synonym
@c HC_describedAs instead.)
@ingroup decorator_matchers
*/
#ifdef HC_SHORTHAND
#define describedAs HC_describedAs
#endif
@@ -0,0 +1,130 @@
//
// OCHamcrest - HCDescribedAs.m
// Copyright 2012 hamcrest.org. See LICENSE.txt
//
// Created by: Jon Reid, http://qualitycoding.org/
// Docs: http://hamcrest.github.com/OCHamcrest/
// Source: https://github.com/hamcrest/OCHamcrest
//
#import "HCDescribedAs.h"
#import "HCDescription.h"
typedef struct
{
int first;
__unsafe_unretained NSString *second;
} HCPairIntNSString;
/**
Splits string into decimal number (-1 if not found) and remaining string.
*/
static HCPairIntNSString separate(NSString *component)
{
int index = 0;
bool gotIndex = false;
NSUInteger length = [component length];
NSUInteger charIndex;
for (charIndex = 0; charIndex < length; ++charIndex)
{
unichar character = [component characterAtIndex:charIndex];
if (!isdigit(character))
break;
index = index * 10 + character - '0';
gotIndex = true;
}
if (!gotIndex)
return (HCPairIntNSString){ -1, component };
else
return (HCPairIntNSString){ index, [component substringFromIndex:charIndex] };
}
#pragma mark -
@implementation HCDescribedAs
+ (id)describedAs:(NSString *)description
forMatcher:(id<HCMatcher>)aMatcher
overValues:(NSArray *)templateValues
{
return [[self alloc] initWithDescription:description
forMatcher:aMatcher
overValues:templateValues];
}
- (id)initWithDescription:(NSString *)description
forMatcher:(id<HCMatcher>)aMatcher
overValues:(NSArray *)templateValues
{
self = [super init];
if (self)
{
descriptionTemplate = [description copy];
matcher = aMatcher;
values = templateValues;
}
return self;
}
- (BOOL)matches:(id)item
{
return [matcher matches:item];
}
- (void)describeMismatchOf:(id)item to:(id<HCDescription>)mismatchDescription
{
[matcher describeMismatchOf:item to:mismatchDescription];
}
- (void)describeTo:(id<HCDescription>)description
{
NSArray *components = [descriptionTemplate componentsSeparatedByString:@"%"];
bool firstTime = true;
for (NSString *oneComponent in components)
{
if (firstTime)
{
firstTime = false;
[description appendText:oneComponent];
}
else
{
HCPairIntNSString parseIndex = separate(oneComponent);
if (parseIndex.first < 0)
[[description appendText:@"%"] appendText:oneComponent];
else
{
[description appendDescriptionOf:values[(NSUInteger)parseIndex.first]];
[description appendText:parseIndex.second];
}
}
}
}
@end
#pragma mark -
id<HCMatcher> HC_describedAs(NSString *description, id<HCMatcher> matcher, ...)
{
NSMutableArray *valueList = [NSMutableArray array];
va_list args;
va_start(args, matcher);
id value = va_arg(args, id);
while (value != nil)
{
[valueList addObject:value];
value = va_arg(args, id);
}
va_end(args);
return [HCDescribedAs describedAs:description forMatcher:matcher overValues:valueList];
}
@@ -0,0 +1,54 @@
//
// OCHamcrest - HCIs.h
// Copyright 2012 hamcrest.org. See LICENSE.txt
//
// Created by: Jon Reid, http://qualitycoding.org/
// Docs: http://hamcrest.github.com/OCHamcrest/
// Source: https://github.com/hamcrest/OCHamcrest
//
#import <OCHamcrest/HCBaseMatcher.h>
@interface HCIs : HCBaseMatcher
{
id<HCMatcher> matcher;
}
+ (id)is:(id<HCMatcher>)aMatcher;
- (id)initWithMatcher:(id<HCMatcher>)aMatcher;
@end
OBJC_EXPORT id<HCMatcher> HC_is(id match);
/**
is(aMatcher) -
Decorates another matcher, or provides a shortcut to the frequently used @ref is(equalTo(x)).
@param aMatcher The matcher to satisfy, or an expected value for @ref equalTo matching.
This matcher compares the evaluated object to the given matcher.
If the @a aMatcher argument is a matcher, its behavior is retained, but the test may be more
expressive. For example:
@li <code>@ref assertThatInt(value, equalToInt(5))</code>
@li <code>@ref assertThatInt(value, is(equalToInt(5)))</code>
If the @a aMatcher argument is not a matcher, it is wrapped in an @ref equalTo matcher. This
makes the following statements equivalent:
@li <code>@ref assertThat(cheese, equalTo(smelly))</code>
@li <code>@ref assertThat(cheese, is(equalTo(smelly)))</code>
@li <code>@ref assertThat(cheese, is(smelly))</code>
Choose the style that makes your expression most readable. This will vary depending on context.
(In the event of a name clash, don't \#define @c HC_SHORTHAND and use the synonym
@c HC_is instead.)
@ingroup decorator_matchers
*/
#ifdef HC_SHORTHAND
#define is HC_is
#endif
@@ -0,0 +1,54 @@
//
// OCHamcrest - HCIs.m
// Copyright 2012 hamcrest.org. See LICENSE.txt
//
// Created by: Jon Reid, http://qualitycoding.org/
// Docs: http://hamcrest.github.com/OCHamcrest/
// Source: https://github.com/hamcrest/OCHamcrest
//
#import "HCIs.h"
#import "HCDescription.h"
#import "HCWrapInMatcher.h"
@implementation HCIs
+ (id)is:(id<HCMatcher>)aMatcher
{
return [[self alloc] initWithMatcher:aMatcher];
}
- (id)initWithMatcher:(id<HCMatcher>)aMatcher
{
self = [super init];
if (self)
matcher = aMatcher;
return self;
}
- (BOOL)matches:(id)item
{
return [matcher matches:item];
}
- (void)describeMismatchOf:(id)item to:(id<HCDescription>)mismatchDescription
{
[matcher describeMismatchOf:item to:mismatchDescription];
}
- (void)describeTo:(id<HCDescription>)description
{
[description appendDescriptionOf:matcher];
}
@end
#pragma mark -
id<HCMatcher> HC_is(id match)
{
return [HCIs is:HCWrapInMatcher(match)];
}
@@ -0,0 +1,45 @@
//
// OCHamcrest - HCAllOf.h
// Copyright 2012 hamcrest.org. See LICENSE.txt
//
// Created by: Jon Reid, http://qualitycoding.org/
// Docs: http://hamcrest.github.com/OCHamcrest/
// Source: https://github.com/hamcrest/OCHamcrest
//
#import <OCHamcrest/HCBaseMatcher.h>
@interface HCAllOf : HCBaseMatcher
{
NSArray *matchers;
}
+ (id)allOf:(NSArray *)theMatchers;
- (id)initWithMatchers:(NSArray *)theMatchers;
@end
OBJC_EXPORT id<HCMatcher> HC_allOf(id match, ...) NS_REQUIRES_NIL_TERMINATION;
/**
allOf(firstMatcher, ...) -
Matches if all of the given matchers evaluate to @c YES.
@param firstMatcher,... A comma-separated list of matchers ending with @c nil.
The matchers are evaluated from left to right using short-circuit evaluation, so evaluation
stops as soon as a matcher returns @c NO.
Any argument that is not a matcher is implicitly wrapped in an @ref equalTo matcher to check for
equality.
(In the event of a name clash, don't \#define @c HC_SHORTHAND and use the synonym
@c HC_allOf instead.)
@ingroup logical_matchers
*/
#ifdef HC_SHORTHAND
#define allOf HC_allOf
#endif
@@ -0,0 +1,73 @@
//
// OCHamcrest - HCAllOf.m
// Copyright 2012 hamcrest.org. See LICENSE.txt
//
// Created by: Jon Reid, http://qualitycoding.org/
// Docs: http://hamcrest.github.com/OCHamcrest/
// Source: https://github.com/hamcrest/OCHamcrest
//
#import "HCAllOf.h"
#import "HCCollectMatchers.h"
#import "HCDescription.h"
@implementation HCAllOf
+ (id)allOf:(NSArray *)theMatchers
{
return [[self alloc] initWithMatchers:theMatchers];
}
- (id)initWithMatchers:(NSArray *)theMatchers
{
self = [super init];
if (self)
matchers = theMatchers;
return self;
}
- (BOOL)matches:(id)item
{
return [self matches:item describingMismatchTo:nil];
}
- (BOOL)matches:(id)item describingMismatchTo:(id<HCDescription>)mismatchDescription
{
for (id<HCMatcher> oneMatcher in matchers)
{
if (![oneMatcher matches:item])
{
[[mismatchDescription appendDescriptionOf:oneMatcher] appendText:@" "];
[oneMatcher describeMismatchOf:item to:mismatchDescription];
return NO;
}
}
return YES;
}
- (void)describeMismatchOf:(id)item to:(id<HCDescription>)mismatchDescription
{
[self matches:item describingMismatchTo:mismatchDescription];
}
- (void)describeTo:(id<HCDescription>)description
{
[description appendList:matchers start:@"(" separator:@" and " end:@")"];
}
@end
#pragma mark -
id<HCMatcher> HC_allOf(id match, ...)
{
va_list args;
va_start(args, match);
NSArray *matcherList = HCCollectMatchers(match, args);
va_end(args);
return [HCAllOf allOf:matcherList];
}
@@ -0,0 +1,45 @@
//
// OCHamcrest - HCAnyOf.h
// Copyright 2012 hamcrest.org. See LICENSE.txt
//
// Created by: Jon Reid, http://qualitycoding.org/
// Docs: http://hamcrest.github.com/OCHamcrest/
// Source: https://github.com/hamcrest/OCHamcrest
//
#import <OCHamcrest/HCBaseMatcher.h>
@interface HCAnyOf : HCBaseMatcher
{
NSArray *matchers;
}
+ (id)anyOf:(NSArray *)theMatchers;
- (id)initWithMatchers:(NSArray *)theMatchers;
@end
OBJC_EXPORT id<HCMatcher> HC_anyOf(id match, ...) NS_REQUIRES_NIL_TERMINATION;
/**
anyOf(firstMatcher, ...) -
Matches if any of the given matchers evaluate to @c YES.
@param firstMatcher,... A comma-separated list of matchers ending with @c nil.
The matchers are evaluated from left to right using short-circuit evaluation, so evaluation
stops as soon as a matcher returns @c YES.
Any argument that is not a matcher is implicitly wrapped in an @ref equalTo matcher to check for
equality.
(In the event of a name clash, don't \#define @c HC_SHORTHAND and use the synonym
@c HC_anyOf instead.)
@ingroup logical_matchers
*/
#ifdef HC_SHORTHAND
#define anyOf HC_anyOf
#endif
@@ -0,0 +1,57 @@
//
// OCHamcrest - HCAnyOf.m
// Copyright 2012 hamcrest.org. See LICENSE.txt
//
// Created by: Jon Reid, http://qualitycoding.org/
// Docs: http://hamcrest.github.com/OCHamcrest/
// Source: https://github.com/hamcrest/OCHamcrest
//
#import "HCAnyOf.h"
#import "HCCollectMatchers.h"
#import "HCDescription.h"
@implementation HCAnyOf
+ (id)anyOf:(NSArray *)theMatchers
{
return [[self alloc] initWithMatchers:theMatchers];
}
- (id)initWithMatchers:(NSArray *)theMatchers
{
self = [super init];
if (self)
matchers = theMatchers;
return self;
}
- (BOOL)matches:(id)item
{
for (id<HCMatcher> oneMatcher in matchers)
if ([oneMatcher matches:item])
return YES;
return NO;
}
- (void)describeTo:(id<HCDescription>)description
{
[description appendList:matchers start:@"(" separator:@" or " end:@")"];
}
@end
#pragma mark -
id<HCMatcher> HC_anyOf(id match, ...)
{
va_list args;
va_start(args, match);
NSArray *matcherList = HCCollectMatchers(match, args);
va_end(args);
return [HCAnyOf anyOf:matcherList];
}
@@ -0,0 +1,63 @@
//
// OCHamcrest - HCIsAnything.h
// Copyright 2012 hamcrest.org. See LICENSE.txt
//
// Created by: Jon Reid, http://qualitycoding.org/
// Docs: http://hamcrest.github.com/OCHamcrest/
// Source: https://github.com/hamcrest/OCHamcrest
//
#import <OCHamcrest/HCBaseMatcher.h>
@interface HCIsAnything : HCBaseMatcher
{
NSString *description;
}
+ (id)isAnything;
+ (id)isAnythingWithDescription:(NSString *)aDescription;
- (id)init;
- (id)initWithDescription:(NSString *)aDescription;
@end
OBJC_EXPORT id<HCMatcher> HC_anything(void);
/**
Matches anything.
This matcher always evaluates to @c YES. Specify this in composite matchers when the value of a
particular element is unimportant.
(In the event of a name clash, don't \#define @c HC_SHORTHAND and use the synonym
@c HC_anything instead.)
@ingroup logical_matchers
*/
#ifdef HC_SHORTHAND
#define anything() HC_anything()
#endif
OBJC_EXPORT id<HCMatcher> HC_anythingWithDescription(NSString *aDescription);
/**
anythingWithDescription(description) -
Matches anything.
@param description A string used to describe this matcher.
This matcher always evaluates to @c YES. Specify this in collection matchers when the value of a
particular element in a collection is unimportant.
(In the event of a name clash, don't \#define @c HC_SHORTHAND and use the synonym
@c HC_anything instead.)
@ingroup logical_matchers
*/
#ifdef HC_SHORTHAND
#define anythingWithDescription HC_anythingWithDescription
#endif
@@ -0,0 +1,64 @@
//
// OCHamcrest - HCIsAnything.m
// Copyright 2012 hamcrest.org. See LICENSE.txt
//
// Created by: Jon Reid, http://qualitycoding.org/
// Docs: http://hamcrest.github.com/OCHamcrest/
// Source: https://github.com/hamcrest/OCHamcrest
//
#import "HCIsAnything.h"
#import "HCDescription.h"
@implementation HCIsAnything
+ (id)isAnything
{
return [[self alloc] init];
}
+ (id)isAnythingWithDescription:(NSString *)aDescription
{
return [[self alloc] initWithDescription:aDescription];
}
- (id)init
{
self = [self initWithDescription:@"ANYTHING"];
return self;
}
- (id)initWithDescription:(NSString *)aDescription
{
self = [super init];
if (self)
description = [aDescription copy];
return self;
}
- (BOOL)matches:(id)item
{
return YES;
}
- (void)describeTo:(id<HCDescription>)aDescription
{
[aDescription appendText:description];
}
@end
#pragma mark -
id<HCMatcher> HC_anything()
{
return [HCIsAnything isAnything];
}
id<HCMatcher> HC_anythingWithDescription(NSString *description)
{
return [HCIsAnything isAnythingWithDescription:description];
}
@@ -0,0 +1,47 @@
//
// OCHamcrest - HCIsNot.h
// Copyright 2012 hamcrest.org. See LICENSE.txt
//
// Created by: Jon Reid, http://qualitycoding.org/
// Docs: http://hamcrest.github.com/OCHamcrest/
// Source: https://github.com/hamcrest/OCHamcrest
//
#import <OCHamcrest/HCBaseMatcher.h>
@interface HCIsNot : HCBaseMatcher
{
id<HCMatcher> matcher;
}
+ (id)isNot:(id<HCMatcher>)aMatcher;
- (id)initNot:(id<HCMatcher>)aMatcher;
@end
OBJC_EXPORT id<HCMatcher> HC_isNot(id aMatcher);
/**
isNot(aMatcher) -
Inverts the given matcher to its logical negation.
@param aMatcher The matcher to negate.
This matcher compares the evaluated object to the negation of the given matcher. If the
@a aMatcher argument is not a matcher, it is implicitly wrapped in an @ref equalTo matcher to
check for equality, and thus matches for inequality.
Examples:
@li <code>@ref assertThat(cheese, isNot(equalTo(smelly)))</code>
@li <code>@ref assertThat(cheese, isNot(smelly))</code>
(In the event of a name clash, don't \#define @c HC_SHORTHAND and use the synonym
@c HC_isNot instead.)
@ingroup logical_matchers
*/
#ifdef HC_SHORTHAND
#define isNot HC_isNot
#endif
@@ -0,0 +1,49 @@
//
// OCHamcrest - HCIsNot.m
// Copyright 2012 hamcrest.org. See LICENSE.txt
//
// Created by: Jon Reid, http://qualitycoding.org/
// Docs: http://hamcrest.github.com/OCHamcrest/
// Source: https://github.com/hamcrest/OCHamcrest
//
#import "HCIsNot.h"
#import "HCDescription.h"
#import "HCWrapInMatcher.h"
@implementation HCIsNot
+ (id)isNot:(id<HCMatcher>)aMatcher
{
return [[self alloc] initNot:aMatcher];
}
- (id)initNot:(id<HCMatcher>)aMatcher
{
self = [super init];
if (self)
matcher = aMatcher;
return self;
}
- (BOOL)matches:(id)item
{
return ![matcher matches:item];
}
- (void)describeTo:(id<HCDescription>)description
{
[[description appendText:@"not "] appendDescriptionOf:matcher];
}
@end
#pragma mark -
id<HCMatcher> HC_isNot(id aMatcher)
{
return [HCIsNot isNot:HCWrapInMatcher(aMatcher)];
}
@@ -0,0 +1,95 @@
//
// OCHamcrest - HCBoxNumber.h
// Copyright 2012 hamcrest.org. See LICENSE.txt
//
// Created by: Jon Reid, http://qualitycoding.org/
// Docs: http://hamcrest.github.com/OCHamcrest/
// Source: https://github.com/hamcrest/OCHamcrest
//
#import <Foundation/Foundation.h>
#ifdef __cplusplus
namespace hamcrest {
/**
Boxes a scalar value in an NSNumber, specialized per type.
@b Deprecated
@ingroup number_matchers
*/
template <typename T>
inline
NSNumber *boxNumber(T value) __attribute__((deprecated));
{ return nil; }
template <>
inline
NSNumber *boxNumber(BOOL value)
{ return [NSNumber numberWithBool:value]; }
template <>
inline
NSNumber *boxNumber(char value)
{ return [NSNumber numberWithChar:value]; }
template <>
inline
NSNumber *boxNumber(double value)
{ return [NSNumber numberWithDouble:value]; }
template <>
inline
NSNumber *boxNumber(float value)
{ return [NSNumber numberWithFloat:value]; }
template <>
inline
NSNumber *boxNumber(int value)
{ return [NSNumber numberWithInt:value]; }
template <>
inline
NSNumber *boxNumber(long value)
{ return [NSNumber numberWithLong:value]; }
template <>
inline
NSNumber *boxNumber(long long value)
{ return [NSNumber numberWithLongLong:value]; }
template <>
inline
NSNumber *boxNumber(short value)
{ return [NSNumber numberWithShort:value]; }
template <>
inline
NSNumber *boxNumber(unsigned char value)
{ return [NSNumber numberWithUnsignedChar:value]; }
template <>
inline
NSNumber *boxNumber(unsigned int value)
{ return [NSNumber numberWithUnsignedInt:value]; }
template <>
inline
NSNumber *boxNumber(unsigned long value)
{ return [NSNumber numberWithUnsignedLong:value]; }
template <>
inline
NSNumber *boxNumber(unsigned long long value)
{ return [NSNumber numberWithUnsignedLongLong:value]; }
template <>
inline
NSNumber *boxNumber(unsigned short value)
{ return [NSNumber numberWithUnsignedShort:value]; }
} // namespace hamcrest
#endif // __cplusplus
@@ -0,0 +1,47 @@
//
// OCHamcrest - HCIsCloseTo.h
// Copyright 2012 hamcrest.org. See LICENSE.txt
//
// Created by: Jon Reid, http://qualitycoding.org/
// Docs: http://hamcrest.github.com/OCHamcrest/
// Source: https://github.com/hamcrest/OCHamcrest
//
#import <OCHamcrest/HCBaseMatcher.h>
@interface HCIsCloseTo : HCBaseMatcher
{
double value;
double delta;
}
+ (id)isCloseTo:(double)aValue within:(double)aDelta;
- (id)initWithValue:(double)aValue delta:(double)aDelta;
@end
OBJC_EXPORT id<HCMatcher> HC_closeTo(double aValue, double aDelta);
/**
closeTo(aValue, aDelta) -
Matches if object is a number close to a given value, within a given delta.
@param aValue The @c double value to compare against as the expected value.
@param aDelta The @c double maximum delta between the values for which the numbers are considered close.
This matcher invokes @c -doubleValue on the evaluated object to get its value as a @c double.
The result is compared against @a aValue to see if the difference is within a positive @a aDelta.
Example:
@li @ref closeTo(3.0, 0.25)
(In the event of a name clash, don't \#define @c HC_SHORTHAND and use the synonym
@c HC_closeTo instead.)
@ingroup number_matchers
*/
#ifdef HC_SHORTHAND
#define closeTo HC_closeTo
#endif
@@ -0,0 +1,70 @@
//
// OCHamcrest - HCIsCloseTo.m
// Copyright 2012 hamcrest.org. See LICENSE.txt
//
// Created by: Jon Reid, http://qualitycoding.org/
// Docs: http://hamcrest.github.com/OCHamcrest/
// Source: https://github.com/hamcrest/OCHamcrest
//
#import "HCIsCloseTo.h"
#import "HCDescription.h"
@implementation HCIsCloseTo
+ (id)isCloseTo:(double)aValue within:(double)aDelta
{
return [[self alloc] initWithValue:aValue delta:aDelta];
}
- (id)initWithValue:(double)aValue delta:(double)aDelta
{
self = [super init];
if (self)
{
value = aValue;
delta = aDelta;
}
return self;
}
- (BOOL)matches:(id)item
{
if (![item isKindOfClass:[NSNumber class]])
return NO;
return fabs([item doubleValue] - value) <= delta;
}
- (void)describeMismatchOf:(id)item to:(id<HCDescription>)mismatchDescription
{
if (![item isKindOfClass:[NSNumber class]])
[super describeMismatchOf:item to:mismatchDescription];
else
{
double actualDelta = fabs([item doubleValue] - value);
[[[mismatchDescription appendDescriptionOf:item]
appendText:@" differed by "]
appendDescriptionOf:@(actualDelta)];
}
}
- (void)describeTo:(id<HCDescription>)description
{
[[[[description appendText:@"a numeric value within "]
appendDescriptionOf:@(delta)]
appendText:@" of "]
appendDescriptionOf:@(value)];
}
@end
#pragma mark -
id<HCMatcher> HC_closeTo(double value, double delta)
{
return [HCIsCloseTo isCloseTo:value within:delta];
}
@@ -0,0 +1,325 @@
//
// OCHamcrest - HCIsEqualToNumber.h
// Copyright 2012 hamcrest.org. See LICENSE.txt
//
// Created by: Jon Reid, http://qualitycoding.org/
// Docs: http://hamcrest.github.com/OCHamcrest/
// Source: https://github.com/hamcrest/OCHamcrest
//
#import <OCHamcrest/HCBaseMatcher.h>
OBJC_EXPORT id<HCMatcher> HC_equalToBool(BOOL value);
/**
equalToBool(value) -
Matches if object is equal to @c NSNumber created from a @c BOOL.
@param value The @c BOOL value from which to create an @c NSNumber.
This matcher creates an @c NSNumber object from a @c BOOL @a value and compares the evaluated
object to it for equality.
(In the event of a name clash, don't \#define @c HC_SHORTHAND and use the synonym
@c HC_equalToBool instead.)
@ingroup primitive_number_matchers
*/
#ifdef HC_SHORTHAND
#define equalToBool HC_equalToBool
#endif
OBJC_EXPORT id<HCMatcher> HC_equalToChar(char value);
/**
equalToChar(value) -
Matches if object is equal to @c NSNumber created from a @c char.
@param value The @c char value from which to create an @c NSNumber.
This matcher creates an @c NSNumber object from a @c char @a value and compares the evaluated
object to it for equality.
(In the event of a name clash, don't \#define @c HC_SHORTHAND and use the synonym
@c HC_equalToChar instead.)
@ingroup primitive_number_matchers
*/
#ifdef HC_SHORTHAND
#define equalToChar HC_equalToChar
#endif
OBJC_EXPORT id<HCMatcher> HC_equalToDouble(double value);
/**
equalToDouble(value) -
Matches if object is equal to @c NSNumber created from a @c double.
@param value The @c double value from which to create an @c NSNumber.
This matcher creates an @c NSNumber object from a @c double @a value and compares the evaluated
object to it for equality.
(In the event of a name clash, don't \#define @c HC_SHORTHAND and use the synonym
@c HC_equalToDouble instead.)
@ingroup primitive_number_matchers
*/
#ifdef HC_SHORTHAND
#define equalToDouble HC_equalToDouble
#endif
OBJC_EXPORT id<HCMatcher> HC_equalToFloat(float value);
/**
equalToFloat(value) -
Matches if object is equal to @c NSNumber created from a @c float.
@param value The @c float value from which to create an @c NSNumber.
This matcher creates an @c NSNumber object from a @c float @a value and compares the evaluated
object to it for equality.
(In the event of a name clash, don't \#define @c HC_SHORTHAND and use the synonym
@c HC_equalToFloat instead.)
@ingroup primitive_number_matchers
*/
#ifdef HC_SHORTHAND
#define equalToFloat HC_equalToFloat
#endif
OBJC_EXPORT id<HCMatcher> HC_equalToInt(int value);
/**
equalToInt(value) -
Matches if object is equal to @c NSNumber created from an @c int.
@param value The @c int value from which to create an @c NSNumber.
This matcher creates an @c NSNumber object from a @c int @a value and compares the evaluated
object to it for equality.
(In the event of a name clash, don't \#define @c HC_SHORTHAND and use the synonym
@c HC_equalToInt instead.)
@ingroup primitive_number_matchers
*/
#ifdef HC_SHORTHAND
#define equalToInt HC_equalToInt
#endif
OBJC_EXPORT id<HCMatcher> HC_equalToLong(long value);
/**
equalToLong(value) -
Matches if object is equal to @c NSNumber created from a @c long.
@param value The @c long value from which to create an @c NSNumber.
This matcher creates an @c NSNumber object from a @c long @a value and compares the evaluated
object to it for equality.
(In the event of a name clash, don't \#define @c HC_SHORTHAND and use the synonym
@c HC_equalToLong instead.)
@ingroup primitive_number_matchers
*/
#ifdef HC_SHORTHAND
#define equalToLong HC_equalToLong
#endif
OBJC_EXPORT id<HCMatcher> HC_equalToLongLong(long long value);
/**
equalToLongLong(value) -
Matches if object is equal to @c NSNumber created from a <code>long long</code>.
@param value The <code>long long</code> value from which to create an @c NSNumber.
This matcher creates an @c NSNumber object from a <code>long long</code> @a value and compares
the evaluated object to it for equality.
(In the event of a name clash, don't \#define @c HC_SHORTHAND and use the synonym
@c HC_equalToLongLong instead.)
@ingroup primitive_number_matchers
*/
#ifdef HC_SHORTHAND
#define equalToLongLong HC_equalToLongLong
#endif
OBJC_EXPORT id<HCMatcher> HC_equalToShort(short value);
/**
equalToShort(value) -
Matches if object is equal to @c NSNumber created from a @c short.
@param value The @c short value from which to create an @c NSNumber.
This matcher creates an @c NSNumber object from a @c short @a value and compares the evaluated
object to it for equality.
(In the event of a name clash, don't \#define @c HC_SHORTHAND and use the synonym
@c HC_equalToShort instead.)
@ingroup primitive_number_matchers
*/
#ifdef HC_SHORTHAND
#define equalToShort HC_equalToShort
#endif
OBJC_EXPORT id<HCMatcher> HC_equalToUnsignedChar(unsigned char value);
/**
equalToUnsignedChar(value) -
Matches if object is equal to @c NSNumber created from an <code>unsigned char</code>.
@param value The <code>unsigned char</code> value from which to create an @c NSNumber.
This matcher creates an @c NSNumber object from an <code>unsigned char</code> @a value and
compares the evaluated object to it for equality.
(In the event of a name clash, don't \#define @c HC_SHORTHAND and use the synonym
@c HC_equalToUnsignedChar instead.)
@ingroup primitive_number_matchers
*/
#ifdef HC_SHORTHAND
#define equalToUnsignedChar HC_equalToUnsignedChar
#endif
OBJC_EXPORT id<HCMatcher> HC_equalToUnsignedInt(unsigned int value);
/**
equalToUnsignedInt(value) -
Matches if object is equal to @c NSNumber created from an <code>unsigned int</code>.
@param value The <code>unsigned int</code> value from which to create an @c NSNumber.
This matcher creates an @c NSNumber object from an <code>unsigned int</code> @a value and
compares the evaluated object to it for equality.
(In the event of a name clash, don't \#define @c HC_SHORTHAND and use the synonym
@c HC_equalToUnsignedInt instead.)
@ingroup primitive_number_matchers
*/
#ifdef HC_SHORTHAND
#define equalToUnsignedInt HC_equalToUnsignedInt
#endif
OBJC_EXPORT id<HCMatcher> HC_equalToUnsignedLong(unsigned long value);
/**
equalToUnsignedLong(value) -
Matches if object is equal to @c NSNumber created from an <code>unsigned long</code>.
@param value The <code>unsigned long</code> value from which to create an @c NSNumber.
This matcher creates an @c NSNumber object from an <code>unsigned long</code> @a value and
compares the evaluated object to it for equality.
(In the event of a name clash, don't \#define @c HC_SHORTHAND and use the synonym
@c HC_equalToUnsignedLong instead.)
@ingroup primitive_number_matchers
*/
#ifdef HC_SHORTHAND
#define equalToUnsignedLong HC_equalToUnsignedLong
#endif
OBJC_EXPORT id<HCMatcher> HC_equalToUnsignedLongLong(unsigned long long value);
/**
equalToUnsignedLongLong(value) -
Matches if object is equal to @c NSNumber created from an <code>unsigned long long</code>.
@param value The <code>unsigned long long</code> value from which to create an @c NSNumber.
This matcher creates an @c NSNumber object from an <code>unsigned long long</code> @a value and
compares the evaluated object to it for equality.
(In the event of a name clash, don't \#define @c HC_SHORTHAND and use the synonym
@c HC_equalToUnsignedLongLong instead.)
@ingroup primitive_number_matchers
*/
#ifdef HC_SHORTHAND
#define equalToUnsignedLongLong HC_equalToUnsignedLongLong
#endif
OBJC_EXPORT id<HCMatcher> HC_equalToUnsignedShort(unsigned short value);
/**
equalToUnsignedShort(value) -
Matches if object is equal to @c NSNumber created from an <code>unsigned short</code>.
@param value The <code>unsigned short</code> value from which to create an @c NSNumber.
This matcher creates an @c NSNumber object from an <code>unsigned short</code> @a value and
compares the evaluated object to it for equality.
(In the event of a name clash, don't \#define @c HC_SHORTHAND and use the synonym
@c HC_equalToUnsignedShort instead.)
@ingroup primitive_number_matchers
*/
#ifdef HC_SHORTHAND
#define equalToUnsignedShort HC_equalToUnsignedShort
#endif
OBJC_EXPORT id<HCMatcher> HC_equalToInteger(NSInteger value);
/**
equalToInteger(value) -
Matches if object is equal to @c NSNumber created from an @c NSInteger.
@param value The @c NSInteger value from which to create an @c NSNumber.
This matcher creates an @c NSNumber object from an @c NSInteger @a value and compares the
evaluated object to it for equality.
(In the event of a name clash, don't \#define @c HC_SHORTHAND and use the synonym
@c HC_equalToInteger instead.)
@ingroup primitive_number_matchers
*/
#ifdef HC_SHORTHAND
#define equalToInteger HC_equalToInteger
#endif
OBJC_EXPORT id<HCMatcher> HC_equalToUnsignedInteger(NSUInteger value);
/**
equalToUnsignedInteger(value) -
Matches if object is equal to @c NSNumber created from an @c NSUInteger.
@param value The @c NSUInteger value from which to create an @c NSNumber.
This matcher creates an @c NSNumber object from an @c NSUInteger @a value and compares the
evaluated object to it for equality.
(In the event of a name clash, don't \#define @c HC_SHORTHAND and use the synonym
@c HC_equalToUnsignedInteger instead.)
@ingroup primitive_number_matchers
*/
#ifdef HC_SHORTHAND
#define equalToUnsignedInteger HC_equalToUnsignedInteger
#endif
@@ -0,0 +1,35 @@
//
// OCHamcrest - HCIsEqualToNumber.m
// Copyright 2012 hamcrest.org. See LICENSE.txt
//
// Created by: Jon Reid, http://qualitycoding.org/
// Docs: http://hamcrest.github.com/OCHamcrest/
// Source: https://github.com/hamcrest/OCHamcrest
//
#import "HCIsEqualToNumber.h"
#import "HCIsEqual.h"
#define DEFINE_EQUAL_TO_NUMBER(name, type) \
OBJC_EXPORT id<HCMatcher> HC_equalTo ## name(type value) \
{ \
return [HCIsEqual isEqualTo:[NSNumber numberWith ## name :value]]; \
}
DEFINE_EQUAL_TO_NUMBER(Bool, BOOL)
DEFINE_EQUAL_TO_NUMBER(Char, char)
DEFINE_EQUAL_TO_NUMBER(Double, double)
DEFINE_EQUAL_TO_NUMBER(Float, float)
DEFINE_EQUAL_TO_NUMBER(Int, int)
DEFINE_EQUAL_TO_NUMBER(Long, long)
DEFINE_EQUAL_TO_NUMBER(LongLong, long long)
DEFINE_EQUAL_TO_NUMBER(Short, short)
DEFINE_EQUAL_TO_NUMBER(UnsignedChar, unsigned char)
DEFINE_EQUAL_TO_NUMBER(UnsignedInt, unsigned int)
DEFINE_EQUAL_TO_NUMBER(UnsignedLong, unsigned long)
DEFINE_EQUAL_TO_NUMBER(UnsignedLongLong, unsigned long long)
DEFINE_EQUAL_TO_NUMBER(UnsignedShort, unsigned short)
DEFINE_EQUAL_TO_NUMBER(Integer, NSInteger)
DEFINE_EQUAL_TO_NUMBER(UnsignedInteger, NSUInteger)
@@ -0,0 +1,387 @@
//
// OCHamcrest - HCNumberAssert.h
// Copyright 2012 hamcrest.org. See LICENSE.txt
//
// Created by: Jon Reid, http://qualitycoding.org/
// Docs: http://hamcrest.github.com/OCHamcrest/
// Source: https://github.com/hamcrest/OCHamcrest
//
#import <Foundation/Foundation.h>
@protocol HCMatcher;
OBJC_EXPORT void HC_assertThatBoolWithLocation(id testCase, BOOL actual,
id<HCMatcher> matcher, const char* fileName, int lineNumber);
#define HC_assertThatBool(actual, matcher) \
HC_assertThatBoolWithLocation(self, actual, matcher, __FILE__, __LINE__)
/**
assertThatBool(actual, matcher) -
Asserts that @c BOOL actual value, converted to an @c NSNumber, satisfies matcher.
@param actual The @c BOOL value to convert to an @c NSNumber for evaluation.
@param matcher The matcher to satisfy as the expected condition.
(In the event of a name clash, don't \#define @c HC_SHORTHAND and use the synonym
@c HC_assertThatBool instead.)
@ingroup integration_numeric
*/
#ifdef HC_SHORTHAND
#define assertThatBool HC_assertThatBool
#endif
#pragma mark -
OBJC_EXPORT void HC_assertThatCharWithLocation(id testCase, char actual,
id<HCMatcher> matcher, const char* fileName, int lineNumber);
#define HC_assertThatChar(actual, matcher) \
HC_assertThatCharWithLocation(self, actual, matcher, __FILE__, __LINE__)
/**
assertThatChar(actual, matcher) -
Asserts that @c char actual value, converted to an @c NSNumber, satisfies matcher.
@param actual The @c char value to convert to an @c NSNumber for evaluation.
@param matcher The matcher to satisfy as the expected condition.
(In the event of a name clash, don't \#define @c HC_SHORTHAND and use the synonym
@c HC_assertThatChar instead.)
@ingroup integration_numeric
*/
#ifdef HC_SHORTHAND
#define assertThatChar HC_assertThatChar
#endif
#pragma mark -
OBJC_EXPORT void HC_assertThatDoubleWithLocation(id testCase, double actual,
id<HCMatcher> matcher, const char* fileName, int lineNumber);
#define HC_assertThatDouble(actual, matcher) \
HC_assertThatDoubleWithLocation(self, actual, matcher, __FILE__, __LINE__)
/**
HC_assertThatDouble(actual, matcher) -
Asserts that @c double actual value, converted to an @c NSNumber, satisfies matcher.
@param actual The @c double value to convert to an @c NSNumber for evaluation.
@param matcher The matcher to satisfy as the expected condition.
(In the event of a name clash, don't \#define @c HC_SHORTHAND and use the synonym
@c HC_assertThatDouble instead.)
@ingroup integration_numeric
*/
#ifdef HC_SHORTHAND
#define assertThatDouble HC_assertThatDouble
#endif
#pragma mark -
OBJC_EXPORT void HC_assertThatFloatWithLocation(id testCase, float actual,
id<HCMatcher> matcher, const char* fileName, int lineNumber);
#define HC_assertThatFloat(actual, matcher) \
HC_assertThatFloatWithLocation(self, actual, matcher, __FILE__, __LINE__)
/**
assertThatFloat(actual, matcher) -
Asserts that @c float actual value, converted to an @c NSNumber, satisfies matcher.
@param actual The @c float value to convert to an @c NSNumber for evaluation.
@param matcher The matcher to satisfy as the expected condition.
(In the event of a name clash, don't \#define @c HC_SHORTHAND and use the synonym
@c HC_assertThatFloat instead.)
@ingroup integration_numeric
*/
#ifdef HC_SHORTHAND
#define assertThatFloat HC_assertThatFloat
#endif
#pragma mark -
OBJC_EXPORT void HC_assertThatIntWithLocation(id testCase, int actual,
id<HCMatcher> matcher, const char* fileName, int lineNumber);
#define HC_assertThatInt(actual, matcher) \
HC_assertThatIntWithLocation(self, actual, matcher, __FILE__, __LINE__)
/**
assertThatInt(actual, matcher) -
Asserts that @c int actual value, converted to an @c NSNumber, satisfies matcher.
@param actual The @c int value to convert to an @c NSNumber for evaluation.
@param matcher The matcher to satisfy as the expected condition.
(In the event of a name clash, don't \#define @c HC_SHORTHAND and use the synonym
@c HC_assertThatInt instead.)
@ingroup integration_numeric
*/
#ifdef HC_SHORTHAND
#define assertThatInt HC_assertThatInt
#endif
#pragma mark -
OBJC_EXPORT void HC_assertThatLongWithLocation(id testCase, long actual,
id<HCMatcher> matcher, const char* fileName, int lineNumber);
#define HC_assertThatLong(actual, matcher) \
HC_assertThatLongWithLocation(self, actual, matcher, __FILE__, __LINE__)
/**
assertThatLong(actual, matcher) -
Asserts that @c long actual value, converted to an @c NSNumber, satisfies matcher.
@param actual The @c long value to convert to an @c NSNumber for evaluation.
@param matcher The matcher to satisfy as the expected condition.
(In the event of a name clash, don't \#define @c HC_SHORTHAND and use the synonym
@c HC_assertThatLong instead.)
@ingroup integration_numeric
*/
#ifdef HC_SHORTHAND
#define assertThatLong HC_assertThatLong
#endif
#pragma mark -
OBJC_EXPORT void HC_assertThatLongLongWithLocation(id testCase, long long actual,
id<HCMatcher> matcher, const char* fileName, int lineNumber);
#define HC_assertThatLongLong(actual, matcher) \
HC_assertThatLongLongWithLocation(self, actual, matcher, __FILE__, __LINE__)
/**
assertThatLongLong(actual, matcher) -
Asserts that <code>long long</code> actual value, converted to an @c NSNumber, satisfies
matcher.
@param actual The <code>long long</code> value to convert to an @c NSNumber for evaluation.
@param matcher The matcher to satisfy as the expected condition.
(In the event of a name clash, don't \#define @c HC_SHORTHAND and use the synonym
@c HC_assertThatLongLong instead.)
@ingroup integration_numeric
*/
#ifdef HC_SHORTHAND
#define assertThatLongLong HC_assertThatLongLong
#endif
#pragma mark -
OBJC_EXPORT void HC_assertThatShortWithLocation(id testCase, short actual,
id<HCMatcher> matcher, const char* fileName, int lineNumber);
#define HC_assertThatShort(actual, matcher) \
HC_assertThatShortWithLocation(self, actual, matcher, __FILE__, __LINE__)
/**
assertThatShort(actual, matcher) -
Asserts that @c short actual value, converted to an @c NSNumber, satisfies matcher.
@param actual The @c short value to convert to an @c NSNumber for evaluation.
@param matcher The matcher to satisfy as the expected condition.
(In the event of a name clash, don't \#define @c HC_SHORTHAND and use the synonym
@c HC_assertThatShort instead.)
@ingroup integration_numeric
*/
#ifdef HC_SHORTHAND
#define assertThatShort HC_assertThatShort
#endif
#pragma mark -
OBJC_EXPORT void HC_assertThatUnsignedCharWithLocation(id testCase, unsigned char actual,
id<HCMatcher> matcher, const char* fileName, int lineNumber);
#define HC_assertThatUnsignedChar(actual, matcher) \
HC_assertThatUnsignedCharWithLocation(self, actual, matcher, __FILE__, __LINE__)
/**
assertThatUnsignedChar(actual, matcher) -
Asserts that <code>unsigned char</code> actual value, converted to an @c NSNumber, satisfies
matcher.
@param actual The <code>unsigned char</code> value to convert to an @c NSNumber for evaluation.
@param matcher The matcher to satisfy as the expected condition.
(In the event of a name clash, don't \#define @c HC_SHORTHAND and use the synonym
@c HC_assertThatUnsignedChar instead.)
@ingroup integration_numeric
*/
#ifdef HC_SHORTHAND
#define assertThatUnsignedChar HC_assertThatUnsignedChar
#endif
#pragma mark -
OBJC_EXPORT void HC_assertThatUnsignedIntWithLocation(id testCase, unsigned int actual,
id<HCMatcher> matcher, const char* fileName, int lineNumber);
#define HC_assertThatUnsignedInt(actual, matcher) \
HC_assertThatUnsignedIntWithLocation(self, actual, matcher, __FILE__, __LINE__)
/**
assertThatUnsignedInt(actual, matcher) -
Asserts that <code>unsigned int</code> actual value, converted to an @c NSNumber, satisfies
matcher.
@param actual The <code>unsigned int</code> value to convert to an @c NSNumber for evaluation @param matcher The matcher to satisfy as the expected condition.
(In the event of a name clash, don't \#define @c HC_SHORTHAND and use the synonym
@c HC_assertThatUnsignedInt instead.)
@ingroup integration_numeric
*/
#ifdef HC_SHORTHAND
#define assertThatUnsignedInt HC_assertThatUnsignedInt
#endif
#pragma mark -
OBJC_EXPORT void HC_assertThatUnsignedLongWithLocation(id testCase, unsigned long actual,
id<HCMatcher> matcher, const char* fileName, int lineNumber);
#define HC_assertThatUnsignedLong(actual, matcher) \
HC_assertThatUnsignedLongWithLocation(self, actual, matcher, __FILE__, __LINE__)
/**
assertThatUnsignedLong(actual, matcher) -
Asserts that <code>unsigned long</code> actual value, converted to an @c NSNumber, satisfies
matcher.
@param actual The <code>unsigned long</code> value to convert to an @c NSNumber for evaluation @param matcher The matcher to satisfy as the expected condition.
(In the event of a name clash, don't \#define @c HC_SHORTHAND and use the synonym
@c HC_assertThatUnsignedLong instead.)
@ingroup integration_numeric
*/
#ifdef HC_SHORTHAND
#define assertThatUnsignedLong HC_assertThatUnsignedLong
#endif
#pragma mark -
OBJC_EXPORT void HC_assertThatUnsignedLongLongWithLocation(id testCase, unsigned long long actual,
id<HCMatcher> matcher, const char* fileName, int lineNumber);
#define HC_assertThatUnsignedLongLong(actual, matcher) \
HC_assertThatUnsignedLongLongWithLocation(self, actual, matcher, __FILE__, __LINE__)
/**
assertThatUnsignedLongLong(actual, matcher) -
Asserts that <code>unsigned long long</code> actual value, converted to an @c NSNumber,
satisfies matcher.
@param actual The <code>unsigned long long</code> value to convert to an @c NSNumber for evaluation @param matcher The matcher to satisfy as the expected condition.
(In the event of a name clash, don't \#define @c HC_SHORTHAND and use the synonym
@c HC_assertThatUnsignedLongLong instead.)
@ingroup integration_numeric
*/
#ifdef HC_SHORTHAND
#define assertThatUnsignedLongLong HC_assertThatUnsignedLongLong
#endif
#pragma mark -
OBJC_EXPORT void HC_assertThatUnsignedShortWithLocation(id testCase, unsigned short actual,
id<HCMatcher> matcher, const char* fileName, int lineNumber);
#define HC_assertThatUnsignedShort(actual, matcher) \
HC_assertThatUnsignedShortWithLocation(self, actual, matcher, __FILE__, __LINE__)
/**
assertThatUnsignedShort(actual, matcher) -
Asserts that <code>unsigned short</code> actual value, converted to an @c NSNumber, satisfies
matcher.
@param actual The <code>unsigned short</code> value to convert to an @c NSNumber for evaluation @param matcher The matcher to satisfy as the expected condition.
(In the event of a name clash, don't \#define @c HC_SHORTHAND and use the synonym
@c HC_assertThatUnsignedShort instead.)
@ingroup integration_numeric
*/
#ifdef HC_SHORTHAND
#define assertThatUnsignedShort HC_assertThatUnsignedShort
#endif
#pragma mark -
OBJC_EXPORT void HC_assertThatIntegerWithLocation(id testCase, NSInteger actual,
id<HCMatcher> matcher, const char* fileName, int lineNumber);
#define HC_assertThatInteger(actual, matcher) \
HC_assertThatIntegerWithLocation(self, actual, matcher, __FILE__, __LINE__)
/**
assertThatInteger(actual, matcher) -
Asserts that @c NSInteger actual value, converted to an @c NSNumber, satisfies matcher.
@param actual The @c NSInteger value to convert to an @c NSNumber for evaluation.
@param matcher The matcher to satisfy as the expected condition.
(In the event of a name clash, don't \#define @c HC_SHORTHAND and use the synonym
@c HC_assertThatInteger instead.)
@ingroup integration_numeric
*/
#ifdef HC_SHORTHAND
#define assertThatInteger HC_assertThatInteger
#endif
#pragma mark -
OBJC_EXPORT void HC_assertThatUnsignedIntegerWithLocation(id testCase, NSUInteger actual,
id<HCMatcher> matcher, const char* fileName, int lineNumber);
#define HC_assertThatUnsignedInteger(actual, matcher) \
HC_assertThatUnsignedIntegerWithLocation(self, actual, matcher, __FILE__, __LINE__)
/**
assertThatUnsignedInteger(actual, matcher) -
Asserts that @c NSUInteger actual value, converted to an @c NSNumber, satisfies matcher.
@param actual The @c NSUInteger value to convert to an @c NSNumber for evaluation.
@param matcher The matcher to satisfy as the expected condition.
(In the event of a name clash, don't \#define @c HC_SHORTHAND and use the synonym
@c HC_assertThatUnsignedInteger instead.)
@ingroup integration_numeric
*/
#ifdef HC_SHORTHAND
#define assertThatUnsignedInteger HC_assertThatUnsignedInteger
#endif
@@ -0,0 +1,36 @@
//
// OCHamcrest - HCNumberAssert.m
// Copyright 2012 hamcrest.org. See LICENSE.txt
//
// Created by: Jon Reid, http://qualitycoding.org/
// Docs: http://hamcrest.github.com/OCHamcrest/
// Source: https://github.com/hamcrest/OCHamcrest
//
#import "HCNumberAssert.h"
#import "HCAssertThat.h"
#define DEFINE_NUMBER_ASSERT(name, type) \
OBJC_EXPORT void HC_assertThat ## name ## WithLocation(id testCase, type actual, id<HCMatcher> matcher, \
const char* fileName, int lineNumber) \
{ \
HC_assertThatWithLocation(testCase, [NSNumber numberWith ## name :actual], matcher, fileName, lineNumber); \
}
DEFINE_NUMBER_ASSERT(Bool, BOOL)
DEFINE_NUMBER_ASSERT(Char, char)
DEFINE_NUMBER_ASSERT(Double, double)
DEFINE_NUMBER_ASSERT(Float, float)
DEFINE_NUMBER_ASSERT(Int, int)
DEFINE_NUMBER_ASSERT(Long, long)
DEFINE_NUMBER_ASSERT(LongLong, long long)
DEFINE_NUMBER_ASSERT(Short, short)
DEFINE_NUMBER_ASSERT(UnsignedChar, unsigned char)
DEFINE_NUMBER_ASSERT(UnsignedInt, unsigned int)
DEFINE_NUMBER_ASSERT(UnsignedLong, unsigned long)
DEFINE_NUMBER_ASSERT(UnsignedLongLong, unsigned long long)
DEFINE_NUMBER_ASSERT(UnsignedShort, unsigned short)
DEFINE_NUMBER_ASSERT(Integer, NSInteger)
DEFINE_NUMBER_ASSERT(UnsignedInteger, NSUInteger)
@@ -0,0 +1,115 @@
//
// OCHamcrest - HCOrderingComparison.h
// Copyright 2012 hamcrest.org. See LICENSE.txt
//
// Created by: Jon Reid, http://qualitycoding.org/
// Docs: http://hamcrest.github.com/OCHamcrest/
// Source: https://github.com/hamcrest/OCHamcrest
//
#import <OCHamcrest/HCBaseMatcher.h>
@interface HCOrderingComparison : HCBaseMatcher
{
id expected;
NSComparisonResult minCompare;
NSComparisonResult maxCompare;
NSString *comparisonDescription;
}
+ (id)compare:(id)expectedValue
minCompare:(NSComparisonResult)min
maxCompare:(NSComparisonResult)max
comparisonDescription:(NSString *)comparisonDescription;
- (id)initComparing:(id)expectedValue
minCompare:(NSComparisonResult)min
maxCompare:(NSComparisonResult)max
comparisonDescription:(NSString *)comparisonDescription;
@end
OBJC_EXPORT id<HCMatcher> HC_greaterThan(id expected);
/**
greaterThan(aNumber) -
Matches if object is greater than a given number.
@param aNumber The @c NSNumber to compare against.
Example:
@li @ref greaterThan(\@5)
(In the event of a name clash, don't \#define @c HC_SHORTHAND and use the synonym
@c HC_greaterThan instead.)
@ingroup number_matchers
*/
#ifdef HC_SHORTHAND
#define greaterThan HC_greaterThan
#endif
OBJC_EXPORT id<HCMatcher> HC_greaterThanOrEqualTo(id expected);
/**
greaterThanOrEqualTo(aNumber) -
Matches if object is greater than or equal to a given number.
@param aNumber The @c NSNumber to compare against.
Example:
@li @ref greaterThanOrEqualTo(\@5)
(In the event of a name clash, don't \#define @c HC_SHORTHAND and use the synonym
@c HC_greaterThanOrEqualTo instead.)
@ingroup number_matchers
*/
#ifdef HC_SHORTHAND
#define greaterThanOrEqualTo HC_greaterThanOrEqualTo
#endif
OBJC_EXPORT id<HCMatcher> HC_lessThan(id expected);
/**
lessThan(aNumber) -
Matches if object is less than a given number.
@param aNumber The @c NSNumber to compare against.
Example:
@li @ref lessThan(\@5)
(In the event of a name clash, don't \#define @c HC_SHORTHAND and use the synonym
@c HC_lessThan instead.)
@ingroup number_matchers
*/
#ifdef HC_SHORTHAND
#define lessThan HC_lessThan
#endif
OBJC_EXPORT id<HCMatcher> HC_lessThanOrEqualTo(id expected);
/**
lessThanOrEqualTo(aNumber) -
Matches if object is less than or equal to a given number.
@param aNumber The @c NSNumber to compare against.
Example:
@li @ref lessThanOrEqualTo(\@5)
(In the event of a name clash, don't \#define @c HC_SHORTHAND and use the synonym
@c HC_lessThanOrEqualTo instead.)
@ingroup number_matchers
*/
#ifdef HC_SHORTHAND
#define lessThanOrEqualTo HC_lessThanOrEqualTo
#endif
@@ -0,0 +1,103 @@
//
// OCHamcrest - HCOrderingComparison.m
// Copyright 2012 hamcrest.org. See LICENSE.txt
//
// Created by: Jon Reid, http://qualitycoding.org/
// Docs: http://hamcrest.github.com/OCHamcrest/
// Source: https://github.com/hamcrest/OCHamcrest
//
#import "HCOrderingComparison.h"
#import "HCDescription.h"
@implementation HCOrderingComparison
+ (id)compare:(id)expectedValue
minCompare:(NSComparisonResult)min
maxCompare:(NSComparisonResult)max
comparisonDescription:(NSString *)description
{
return [[self alloc] initComparing:expectedValue
minCompare:min
maxCompare:max
comparisonDescription:description];
}
- (id)initComparing:(id)expectedValue
minCompare:(NSComparisonResult)min
maxCompare:(NSComparisonResult)max
comparisonDescription:(NSString *)description
{
if (![expectedValue respondsToSelector:@selector(compare:)])
{
@throw [NSException exceptionWithName: @"UncomparableObject"
reason: @"Object must respond to compare:"
userInfo: nil];
}
self = [super init];
if (self)
{
expected = expectedValue;
minCompare = min;
maxCompare = max;
comparisonDescription = [description copy];
}
return self;
}
- (BOOL)matches:(id)item
{
if (item == nil)
return NO;
NSComparisonResult compare = [expected compare:item];
return minCompare <= compare && compare <= maxCompare;
}
- (void)describeTo:(id<HCDescription>)description
{
[[[[description appendText:@"a value "]
appendText:comparisonDescription]
appendText:@" "]
appendDescriptionOf:expected];
}
@end
#pragma mark -
id<HCMatcher> HC_greaterThan(id aValue)
{
return [HCOrderingComparison compare:aValue
minCompare:NSOrderedAscending
maxCompare:NSOrderedAscending
comparisonDescription:@"greater than"];
}
id<HCMatcher> HC_greaterThanOrEqualTo(id aValue)
{
return [HCOrderingComparison compare:aValue
minCompare:NSOrderedAscending
maxCompare:NSOrderedSame
comparisonDescription:@"greater than or equal to"];
}
id<HCMatcher> HC_lessThan(id aValue)
{
return [HCOrderingComparison compare:aValue
minCompare:NSOrderedDescending
maxCompare:NSOrderedDescending
comparisonDescription:@"less than"];
}
id<HCMatcher> HC_lessThanOrEqualTo(id aValue)
{
return [HCOrderingComparison compare:aValue
minCompare:NSOrderedSame
maxCompare:NSOrderedDescending
comparisonDescription:@"less than or equal to"];
}
@@ -0,0 +1,43 @@
//
// OCHamcrest - HCConformsToProtocol.h
// Copyright 2012 hamcrest.org. See LICENSE.txt
//
// Created by: Todd Farrell
//
#import <OCHamcrest/HCBaseMatcher.h>
@interface HCConformsToProtocol : HCBaseMatcher
{
Protocol *theProtocol;
}
+ (id)conformsTo:(Protocol *)protocol;
- (id)initWithProtocol:(Protocol *)protocol;
@end
OBJC_EXPORT id<HCMatcher> HC_conformsTo(Protocol *aProtocol);
OBJC_EXPORT id<HCMatcher> HC_conformsToProtocol(Protocol *aProtocol) __attribute__((deprecated));
/**
conformsTo(aProtocol) -
Matches if object conforms to a given protocol.
@param aProtocol The protocol to compare against as the expected protocol.
This matcher checks whether the evaluated object conforms to @a aProtocol.
Example:
@li @ref conformsTo(\@protocol(NSObject))
(In the event of a name clash, don't \#define @c HC_SHORTHAND and use the synonym
@c HC_conformsTo instead.)
@ingroup object_matchers
*/
#ifdef HC_SHORTHAND
#define conformsTo HC_conformsTo
#endif
@@ -0,0 +1,55 @@
//
// OCHamcrest - HCConformsToProtocol.m
// Copyright 2012 hamcrest.org. See LICENSE.txt
//
// Created by: Todd Farrell
//
#import "HCConformsToProtocol.h"
#import "HCDescription.h"
#import "HCRequireNonNilObject.h"
@implementation HCConformsToProtocol
+ (id)conformsTo:(Protocol *)protocol
{
return [[self alloc] initWithProtocol:protocol];
}
- (id)initWithProtocol:(Protocol *)aProtocol
{
HCRequireNonNilObject(aProtocol);
self = [super init];
if (self)
theProtocol = aProtocol;
return self;
}
- (BOOL)matches:(id)item
{
return [item conformsToProtocol:theProtocol];
}
- (void)describeTo:(id<HCDescription>)description
{
[[description appendText:@"an object that conforms to "]
appendText:NSStringFromProtocol(theProtocol)];
}
@end
#pragma mark -
id<HCMatcher> HC_conformsTo(Protocol *aProtocol)
{
return [HCConformsToProtocol conformsTo:aProtocol];
}
id<HCMatcher> HC_conformsToProtocol(Protocol *aProtocol)
{
return HC_conformsTo(aProtocol);
}
@@ -0,0 +1,44 @@
//
// OCHamcrest - HCHasDescription.h
// Copyright 2012 hamcrest.org. See LICENSE.txt
//
// Created by: Jon Reid, http://qualitycoding.org/
// Docs: http://hamcrest.github.com/OCHamcrest/
// Source: https://github.com/hamcrest/OCHamcrest
//
#import <OCHamcrest/HCInvocationMatcher.h>
@interface HCHasDescription : HCInvocationMatcher
+ (id)hasDescription:(id<HCMatcher>)descriptionMatcher;
- (id)initWithDescription:(id<HCMatcher>)descriptionMatcher;
@end
OBJC_EXPORT id<HCMatcher> HC_hasDescription(id match);
/**
hasDescription(aMatcher) -
Matches if object's @c -description satisfies a given matcher.
@param aMatcher The matcher to satisfy, or an expected value for @ref equalTo matching.
This matcher invokes @c -description on the evaluated object to get its description, passing the
result to a given matcher for evaluation. If the @a aMatcher argument is not a matcher, it is
implicitly wrapped in an @ref equalTo matcher to check for equality.
Examples:
@li @ref hasDescription(@ref startsWith(\@"foo"))
@li @ref hasDescription(\@"bar")
(In the event of a name clash, don't \#define @c HC_SHORTHAND and use the synonym
@c HC_hasDescription instead.)
@ingroup object_matchers
*/
#ifdef HC_SHORTHAND
#define hasDescription HC_hasDescription
#endif
@@ -0,0 +1,39 @@
//
// OCHamcrest - HCHasDescription.m
// Copyright 2012 hamcrest.org. See LICENSE.txt
//
// Created by: Jon Reid, http://qualitycoding.org/
// Docs: http://hamcrest.github.com/OCHamcrest/
// Source: https://github.com/hamcrest/OCHamcrest
//
#import "HCHasDescription.h"
#import "HCWrapInMatcher.h"
@implementation HCHasDescription
+ (id)hasDescription:(id<HCMatcher>)descriptionMatcher
{
return [[self alloc] initWithDescription:descriptionMatcher];
}
- (id)initWithDescription:(id<HCMatcher>)descriptionMatcher
{
NSInvocation *anInvocation = [HCInvocationMatcher invocationForSelector:@selector(description)
onClass:[NSObject class]];
self = [super initWithInvocation:anInvocation matching:descriptionMatcher];
shortMismatchDescription = YES;
return self;
}
@end
#pragma mark -
id<HCMatcher> HC_hasDescription(id match)
{
return [HCHasDescription hasDescription:HCWrapInMatcher(match)];
}
@@ -0,0 +1,49 @@
//
// OCHamcrest - HCHasProperty.h
// Copyright 2012 hamcrest.org. See LICENSE.txt
//
// Created by: Justin Shacklette
//
#import <OCHamcrest/HCBaseMatcher.h>
@interface HCHasProperty : HCBaseMatcher
{
NSString *propertyName;
id<HCMatcher> valueMatcher;
}
+ (id)hasProperty:(NSString *)property value:(id<HCMatcher>)aValueMatcher;
- (id)initWithProperty:(NSString *)property value:(id<HCMatcher>)aValueMatcher;
@end
OBJC_EXPORT id<HCMatcher> HC_hasProperty(NSString *name, id valueMatch);
/**
hasProperty(name, valueMatcher) -
Matches if object has a method of a given name whose return value satisfies a given matcher.
@param name The name of a method without arguments that returns an object.
@param valueMatcher The matcher to satisfy for the return value, or an expected value for @ref equalTo matching.
This matcher first checks if the evaluated object has a method with a name matching the given
@c name. If so, it invokes the method and sees if the returned value satisfies @c valueMatcher.
While this matcher is called "hasProperty", it's useful for checking the results of any simple
methods, not just properties.
Examples:
@li @ref hasProperty(\@"firstName", \@"Joe")
@li @ref hasProperty(\@"firstName", startsWith(\@"J"))
(In the event of a name clash, don't \#define @c HC_SHORTHAND and use the synonym
@c HC_hasProperty instead.)
@ingroup object_matchers
*/
#ifdef HC_SHORTHAND
#define hasProperty HC_hasProperty
#endif
@@ -0,0 +1,150 @@
//
// OCHamcrest - HCHasProperty.m
// Copyright 2012 hamcrest.org. See LICENSE.txt
//
// Created by: Justin Shacklette
//
#import "HCHasProperty.h"
#import "HCDescription.h"
#import "HCRequireNonNilObject.h"
#import "HCWrapInMatcher.h"
@implementation HCHasProperty
+ (id)hasProperty:(NSString *)property value:(id<HCMatcher>)aValueMatcher
{
return [[self alloc] initWithProperty:property value:aValueMatcher];
}
- (id)initWithProperty:(NSString *)property value:(id<HCMatcher>)aValueMatcher
{
HCRequireNonNilObject(property);
self = [super init];
if (self != nil)
{
propertyName = [property copy];
valueMatcher = aValueMatcher;
}
return self;
}
- (BOOL)matches:(id)item
{
SEL propertyGetter = NSSelectorFromString(propertyName);
if (![item respondsToSelector:propertyGetter])
return NO;
id propertyValue = [self objectFromInvokingSelector:propertyGetter onObject:item];
return [valueMatcher matches:propertyValue];
}
- (id)objectFromInvokingSelector:(SEL)selector onObject:(id)object
{
NSMethodSignature *getterSignature = [object methodSignatureForSelector:selector];
NSInvocation *getterInvocation = [NSInvocation invocationWithMethodSignature:getterSignature];
[getterInvocation setTarget:object];
[getterInvocation setSelector:selector];
[getterInvocation invoke];
__unsafe_unretained id result = nil;
const char *argType = [getterSignature methodReturnType];
if (strncmp(argType, @encode(char), 1) == 0)
{
char charValue;
[getterInvocation getReturnValue:&charValue];
result = @(charValue);
}
else if (strncmp(argType, @encode(int), 1) == 0)
{
int intValue;
[getterInvocation getReturnValue:&intValue];
result = @(intValue);
}
else if (strncmp(argType, @encode(short), 1) == 0)
{
short shortValue;
[getterInvocation getReturnValue:&shortValue];
result = @(shortValue);
}
else if (strncmp(argType, @encode(long), 1) == 0)
{
long longValue;
[getterInvocation getReturnValue:&longValue];
result = @(longValue);
}
else if (strncmp(argType, @encode(long long), 1) == 0)
{
long long longLongValue;
[getterInvocation getReturnValue:&longLongValue];
result = @(longLongValue);
}
else if (strncmp(argType, @encode(unsigned char), 1) == 0)
{
unsigned char unsignedCharValue;
[getterInvocation getReturnValue:&unsignedCharValue];
result = @(unsignedCharValue);
}
else if (strncmp(argType, @encode(unsigned int), 1) == 0)
{
unsigned int unsignedIntValue;
[getterInvocation getReturnValue:&unsignedIntValue];
result = @(unsignedIntValue);
}
else if (strncmp(argType, @encode(unsigned short), 1) == 0)
{
unsigned short unsignedShortValue;
[getterInvocation getReturnValue:&unsignedShortValue];
result = @(unsignedShortValue);
}
else if (strncmp(argType, @encode(unsigned long), 1) == 0)
{
unsigned long unsignedLongValue;
[getterInvocation getReturnValue:&unsignedLongValue];
result = @(unsignedLongValue);
}
else if (strncmp(argType, @encode(unsigned long long), 1) == 0)
{
unsigned long long unsignedLongLongValue;
[getterInvocation getReturnValue:&unsignedLongLongValue];
result = @(unsignedLongLongValue);
}
else if (strncmp(argType, @encode(float), 1) == 0)
{
float floatValue;
[getterInvocation getReturnValue:&floatValue];
result = @(floatValue);
}
else if (strncmp(argType, @encode(double), 1) == 0)
{
double doubleValue;
[getterInvocation getReturnValue:&doubleValue];
result = @(doubleValue);
}
else if (strncmp(argType, @encode(id), 1) == 0)
{
[getterInvocation getReturnValue:&result];
}
return result;
}
- (void)describeTo:(id<HCDescription>)description
{
[[[[description appendText:@"an object with "]
appendText:propertyName]
appendText:@" "]
appendDescriptionOf:valueMatcher];
}
@end
#pragma mark -
id<HCMatcher> HC_hasProperty(NSString *name, id valueMatch)
{
return [HCHasProperty hasProperty:name value:HCWrapInMatcher(valueMatch)];
}
@@ -0,0 +1,44 @@
//
// OCHamcrest - HCIsEqual.h
// Copyright 2012 hamcrest.org. See LICENSE.txt
//
// Created by: Jon Reid, http://qualitycoding.org/
// Docs: http://hamcrest.github.com/OCHamcrest/
// Source: https://github.com/hamcrest/OCHamcrest
//
#import <OCHamcrest/HCBaseMatcher.h>
@interface HCIsEqual : HCBaseMatcher
{
id object;
}
+ (id)isEqualTo:(id)anObject;
- (id)initEqualTo:(id)anObject;
@end
OBJC_EXPORT id<HCMatcher> HC_equalTo(id object);
/**
equalTo(anObject) -
Matches if object is equal to a given object.
@param anObject The object to compare against as the expected value.
This matcher compares the evaluated object to @a anObject for equality, as determined by the
@c -isEqual: method.
If @a anObject is @c nil, the matcher will successfully match @c nil.
(In the event of a name clash, don't \#define @c HC_SHORTHAND and use the synonym
@c HC_equalTo instead.)
@ingroup object_matchers
*/
#ifdef HC_SHORTHAND
#define equalTo HC_equalTo
#endif
@@ -0,0 +1,58 @@
//
// OCHamcrest - HCIsEqual.m
// Copyright 2012 hamcrest.org. See LICENSE.txt
//
// Created by: Jon Reid, http://qualitycoding.org/
// Docs: http://hamcrest.github.com/OCHamcrest/
// Source: https://github.com/hamcrest/OCHamcrest
//
#import "HCIsEqual.h"
#import "HCDescription.h"
@implementation HCIsEqual
+ (id)isEqualTo:(id)anObject
{
return [[self alloc] initEqualTo:anObject];
}
- (id)initEqualTo:(id)anObject
{
self = [super init];
if (self)
object = anObject;
return self;
}
- (BOOL)matches:(id)item
{
if (item == nil)
return object == nil;
else
return [item isEqual:object];
}
- (void)describeTo:(id<HCDescription>)description
{
if ([object conformsToProtocol:@protocol(HCMatcher)])
{
[[[description appendText:@"<"]
appendDescriptionOf:object]
appendText:@">"];
}
else
[description appendDescriptionOf:object];
}
@end
#pragma mark -
id<HCMatcher> HC_equalTo(id object)
{
return [HCIsEqual isEqualTo:object];
}
@@ -0,0 +1,45 @@
//
// OCHamcrest - HCIsInstanceOf.h
// Copyright 2012 hamcrest.org. See LICENSE.txt
//
// Created by: Jon Reid, http://qualitycoding.org/
// Docs: http://hamcrest.github.com/OCHamcrest/
// Source: https://github.com/hamcrest/OCHamcrest
//
#import <OCHamcrest/HCBaseMatcher.h>
@interface HCIsInstanceOf : HCBaseMatcher
{
Class theClass;
}
+ (id)isInstanceOf:(Class)type;
- (id)initWithType:(Class)type;
@end
OBJC_EXPORT id<HCMatcher> HC_instanceOf(Class aClass);
/**
instanceOf(aClass) -
Matches if object is an instance of, or inherits from, a given class.
@param aClass The class to compare against as the expected class.
This matcher checks whether the evaluated object is an instance of @a aClass or an instance of
any class that inherits from @a aClass.
Example:
@li @ref instanceOf([NSString class])
(In the event of a name clash, don't \#define @c HC_SHORTHAND and use the synonym
@c HC_instanceOf instead.)
@ingroup object_matchers
*/
#ifdef HC_SHORTHAND
#define instanceOf HC_instanceOf
#endif
@@ -0,0 +1,52 @@
//
// OCHamcrest - HCIsInstanceOf.m
// Copyright 2012 hamcrest.org. See LICENSE.txt
//
// Created by: Jon Reid, http://qualitycoding.org/
// Docs: http://hamcrest.github.com/OCHamcrest/
// Source: https://github.com/hamcrest/OCHamcrest
//
#import "HCIsInstanceOf.h"
#import "HCDescription.h"
#import "HCRequireNonNilObject.h"
@implementation HCIsInstanceOf
+ (id)isInstanceOf:(Class)type
{
return [[self alloc] initWithType:type];
}
- (id)initWithType:(Class)aClass
{
HCRequireNonNilObject(aClass);
self = [super init];
if (self)
theClass = aClass;
return self;
}
- (BOOL)matches:(id)item
{
return [item isKindOfClass:theClass];
}
- (void)describeTo:(id<HCDescription>)description
{
[[description appendText:@"an instance of "]
appendText:NSStringFromClass(theClass)];
}
@end
#pragma mark -
id<HCMatcher> HC_instanceOf(Class aClass)
{
return [HCIsInstanceOf isInstanceOf:aClass];
}
@@ -0,0 +1,47 @@
//
// OCHamcrest - HCIsNil.h
// Copyright 2012 hamcrest.org. See LICENSE.txt
//
// Created by: Jon Reid, http://qualitycoding.org/
// Docs: http://hamcrest.github.com/OCHamcrest/
// Source: https://github.com/hamcrest/OCHamcrest
//
#import <OCHamcrest/HCBaseMatcher.h>
@interface HCIsNil : HCBaseMatcher
+ (id)isNil;
@end
OBJC_EXPORT id<HCMatcher> HC_nilValue(void);
/**
Matches if object is @c nil.
(In the event of a name clash, don't \#define @c HC_SHORTHAND and use the synonym
@c HC_nilValue instead.)
@ingroup object_matchers
*/
#ifdef HC_SHORTHAND
#define nilValue() HC_nilValue()
#endif
OBJC_EXPORT id<HCMatcher> HC_notNilValue(void);
/**
Matches if object is not @c nil.
(In the event of a name clash, don't \#define @c HC_SHORTHAND and use the synonym
@c HC_notNilValue instead.)
@ingroup object_matchers
*/
#ifdef HC_SHORTHAND
#define notNilValue() HC_notNilValue()
#endif
@@ -0,0 +1,46 @@
//
// OCHamcrest - HCIsNil.m
// Copyright 2012 hamcrest.org. See LICENSE.txt
//
// Created by: Jon Reid, http://qualitycoding.org/
// Docs: http://hamcrest.github.com/OCHamcrest/
// Source: https://github.com/hamcrest/OCHamcrest
//
#import "HCIsNil.h"
#import "HCDescription.h"
#import "HCIsNot.h"
@implementation HCIsNil
+ (id)isNil
{
return [[self alloc] init];
}
- (BOOL)matches:(id)item
{
return item == nil;
}
- (void)describeTo:(id<HCDescription>)description
{
[description appendText:@"nil"];
}
@end
#pragma mark -
id<HCMatcher> HC_nilValue()
{
return [HCIsNil isNil];
}
id<HCMatcher> HC_notNilValue()
{
return HC_isNot([HCIsNil isNil]);
}
@@ -0,0 +1,42 @@
//
// OCHamcrest - HCIsSame.h
// Copyright 2012 hamcrest.org. See LICENSE.txt
//
// Created by: Jon Reid, http://qualitycoding.org/
// Docs: http://hamcrest.github.com/OCHamcrest/
// Source: https://github.com/hamcrest/OCHamcrest
//
#import <OCHamcrest/HCBaseMatcher.h>
@interface HCIsSame : HCBaseMatcher
{
id object;
}
+ (id)isSameAs:(id)anObject;
- (id)initSameAs:(id)anObject;
@end
OBJC_EXPORT id<HCMatcher> HC_sameInstance(id object);
/**
sameInstance(anObject) -
Matches if evaluated object is the same instance as a given object.
@param anObject The object to compare against as the expected value.
This matcher compares the address of the evaluated object to determine if it is the same object
as @a anObject.
(In the event of a name clash, don't \#define @c HC_SHORTHAND and use the synonym
@c HC_sameInstance instead.)
@ingroup object_matchers
*/
#ifdef HC_SHORTHAND
#define sameInstance HC_sameInstance
#endif
@@ -0,0 +1,57 @@
//
// OCHamcrest - HCIsSame.m
// Copyright 2012 hamcrest.org. See LICENSE.txt
//
// Created by: Jon Reid, http://qualitycoding.org/
// Docs: http://hamcrest.github.com/OCHamcrest/
// Source: https://github.com/hamcrest/OCHamcrest
//
#import "HCIsSame.h"
#import "HCDescription.h"
@implementation HCIsSame
+ (id)isSameAs:(id)anObject
{
return [[self alloc] initSameAs:anObject];
}
- (id)initSameAs:(id)anObject
{
self = [super init];
if (self)
object = anObject;
return self;
}
- (BOOL)matches:(id)item
{
return item == object;
}
- (void)describeMismatchOf:(id)item to:(id<HCDescription>)mismatchDescription
{
[mismatchDescription appendText:@"was "];
if (item)
[mismatchDescription appendText:[NSString stringWithFormat:@"%p ", (__bridge void *)item]];
[mismatchDescription appendDescriptionOf:item];
}
- (void)describeTo:(id<HCDescription>)description
{
[[description appendText:[NSString stringWithFormat:@"same instance as %p ", (__bridge void *)object]]
appendDescriptionOf:object];
}
@end
#pragma mark -
id<HCMatcher> HC_sameInstance(id object)
{
return [HCIsSame isSameAs:object];
}
@@ -0,0 +1,49 @@
//
// OCHamcrest - HCIsEqualIgnoringCase.h
// Copyright 2012 hamcrest.org. See LICENSE.txt
//
// Created by: Jon Reid, http://qualitycoding.org/
// Docs: http://hamcrest.github.com/OCHamcrest/
// Source: https://github.com/hamcrest/OCHamcrest
//
#import <OCHamcrest/HCBaseMatcher.h>
@interface HCIsEqualIgnoringCase : HCBaseMatcher
{
NSString *string;
}
+ (id)isEqualIgnoringCase:(NSString *)aString;
- (id)initWithString:(NSString *)aString;
@end
OBJC_EXPORT id<HCMatcher> HC_equalToIgnoringCase(NSString *aString);
/**
equalToIgnoringCase(aString) -
Matches if object is a string equal to a given string, ignoring case differences.
@param aString The string to compare against as the expected value. This value must not be @c nil.
This matcher first checks whether the evaluated object is a string. If so, it compares it with
@a aString, ignoring differences of case.
Example:
@par
@ref equalToIgnoringCase(@"hello world")
will match "heLLo WorlD".
(In the event of a name clash, don't \#define @c HC_SHORTHAND and use the synonym
@c HC_equalToIgnoringCase instead.)
@ingroup text_matchers
*/
#ifdef HC_SHORTHAND
#define equalToIgnoringCase HC_equalToIgnoringCase
#endif
@@ -0,0 +1,55 @@
//
// OCHamcrest - HCIsEqualIgnoringCase.m
// Copyright 2012 hamcrest.org. See LICENSE.txt
//
// Created by: Jon Reid, http://qualitycoding.org/
// Docs: http://hamcrest.github.com/OCHamcrest/
// Source: https://github.com/hamcrest/OCHamcrest
//
#import "HCIsEqualIgnoringCase.h"
#import "HCDescription.h"
#import "HCRequireNonNilObject.h"
@implementation HCIsEqualIgnoringCase
+ (id)isEqualIgnoringCase:(NSString *)aString
{
return [[self alloc] initWithString:aString];
}
- (id)initWithString:(NSString *)aString
{
HCRequireNonNilObject(aString);
self = [super init];
if (self)
string = [aString copy];
return self;
}
- (BOOL)matches:(id)item
{
if (![item isKindOfClass:[NSString class]])
return NO;
return [string caseInsensitiveCompare:item] == NSOrderedSame;
}
- (void)describeTo:(id<HCDescription>)description
{
[[description appendDescriptionOf:string]
appendText:@" ignoring case"];
}
@end
#pragma mark -
id<HCMatcher> HC_equalToIgnoringCase(NSString *aString)
{
return [HCIsEqualIgnoringCase isEqualIgnoringCase:aString];
}
@@ -0,0 +1,50 @@
//
// OCHamcrest - HCIsEqualIgnoringWhiteSpace.h
// Copyright 2012 hamcrest.org. See LICENSE.txt
//
// Created by: Jon Reid, http://qualitycoding.org/
// Docs: http://hamcrest.github.com/OCHamcrest/
// Source: https://github.com/hamcrest/OCHamcrest
//
#import <OCHamcrest/HCBaseMatcher.h>
@interface HCIsEqualIgnoringWhiteSpace : HCBaseMatcher
{
NSString *originalString;
NSString *strippedString;
}
+ (id)isEqualIgnoringWhiteSpace:(NSString *)aString;
- (id)initWithString:(NSString *)aString;
@end
OBJC_EXPORT id<HCMatcher> HC_equalToIgnoringWhiteSpace(NSString *aString);
/**
equalToIgnoringWhiteSpace(aString) -
Matches if object is a string equal to a given string, ignoring differences in whitespace.
@param aString The string to compare against as the expected value. This value must not be @c nil.
This matcher first checks whether the evaluated object is a string. If so, it compares it with
@a aString, ignoring differences in runs of whitespace.
Example:
@par
@ref equalToIgnoringWhiteSpace(@"hello world")
will match @verbatim "hello world" @endverbatim
(In the event of a name clash, don't \#define @c HC_SHORTHAND and use the synonym
@c HC_equalToIgnoringWhiteSpace instead.)
@ingroup text_matchers
*/
#ifdef HC_SHORTHAND
#define equalToIgnoringWhiteSpace HC_equalToIgnoringWhiteSpace
#endif
@@ -0,0 +1,97 @@
//
// OCHamcrest - HCIsEqualIgnoringWhiteSpace.m
// Copyright 2012 hamcrest.org. See LICENSE.txt
//
// Created by: Jon Reid, http://qualitycoding.org/
// Docs: http://hamcrest.github.com/OCHamcrest/
// Source: https://github.com/hamcrest/OCHamcrest
//
#import "HCIsEqualIgnoringWhiteSpace.h"
#import "HCDescription.h"
#import "HCRequireNonNilObject.h"
static void removeTrailingSpace(NSMutableString *string)
{
NSUInteger length = [string length];
if (length > 0)
{
NSUInteger charIndex = length - 1;
if (isspace([string characterAtIndex:charIndex]))
[string deleteCharactersInRange:NSMakeRange(charIndex, 1)];
}
}
static NSMutableString *stripSpace(NSString *string)
{
NSUInteger length = [string length];
NSMutableString *result = [NSMutableString stringWithCapacity:length];
bool lastWasSpace = true;
for (NSUInteger charIndex = 0; charIndex < length; ++charIndex)
{
unichar character = [string characterAtIndex:charIndex];
if (isspace(character))
{
if (!lastWasSpace)
[result appendString:@" "];
lastWasSpace = true;
}
else
{
[result appendFormat:@"%C", character];
lastWasSpace = false;
}
}
removeTrailingSpace(result);
return result;
}
#pragma mark -
@implementation HCIsEqualIgnoringWhiteSpace
+ (id)isEqualIgnoringWhiteSpace:(NSString *)aString
{
return [[self alloc] initWithString:aString];
}
- (id)initWithString:(NSString *)aString
{
HCRequireNonNilObject(aString);
self = [super init];
if (self)
{
originalString = [aString copy];
strippedString = stripSpace(aString);
}
return self;
}
- (BOOL)matches:(id)item
{
if (![item isKindOfClass:[NSString class]])
return NO;
return [strippedString isEqualToString:stripSpace(item)];
}
- (void)describeTo:(id<HCDescription>)description
{
[[description appendDescriptionOf:originalString]
appendText:@" ignoring whitespace"];
}
@end
#pragma mark -
id<HCMatcher> HC_equalToIgnoringWhiteSpace(NSString *aString)
{
return [HCIsEqualIgnoringWhiteSpace isEqualIgnoringWhiteSpace:aString];
}
@@ -0,0 +1,45 @@
//
// OCHamcrest - HCStringContains.h
// Copyright 2012 hamcrest.org. See LICENSE.txt
//
// Created by: Jon Reid, http://qualitycoding.org/
// Docs: http://hamcrest.github.com/OCHamcrest/
// Source: https://github.com/hamcrest/OCHamcrest
//
#import <OCHamcrest/HCSubstringMatcher.h>
@interface HCStringContains : HCSubstringMatcher
+ (id)stringContains:(NSString *)aSubstring;
@end
OBJC_EXPORT id<HCMatcher> HC_containsString(NSString *aSubstring);
/**
containsString(aString) -
Matches if object is a string containing a given string.
@param aString The string to search for. This value must not be @c nil.
This matcher first checks whether the evaluated object is a string. If so, it checks whether it
contains @a aString.
Example:
@par
@ref containsString(@"def")
will match "abcdefg".
(In the event of a name clash, don't \#define @c HC_SHORTHAND and use the synonym
@c HC_containsString instead.)
@ingroup text_matchers
*/
#ifdef HC_SHORTHAND
#define containsString HC_containsString
#endif
@@ -0,0 +1,41 @@
//
// OCHamcrest - HCStringContains.m
// Copyright 2012 hamcrest.org. See LICENSE.txt
//
// Created by: Jon Reid, http://qualitycoding.org/
// Docs: http://hamcrest.github.com/OCHamcrest/
// Source: https://github.com/hamcrest/OCHamcrest
//
#import "HCStringContains.h"
@implementation HCStringContains
+ (id)stringContains:(NSString *)aString
{
return [[self alloc] initWithSubstring:aString];
}
- (BOOL)matches:(id)item
{
if (![item respondsToSelector:@selector(rangeOfString:)])
return NO;
return [item rangeOfString:substring].location != NSNotFound;
}
- (NSString *)relationship
{
return @"containing";
}
@end
#pragma mark -
id<HCMatcher> HC_containsString(NSString *aString)
{
return [HCStringContains stringContains:aString];
}
@@ -0,0 +1,50 @@
//
// OCHamcrest - HCStringContainsInOrder.h
// Copyright 2012 hamcrest.org. See LICENSE.txt
//
// Created by: Jon Reid, http://qualitycoding.org/
// Docs: http://hamcrest.github.com/OCHamcrest/
// Source: https://github.com/hamcrest/OCHamcrest
//
#import <OCHamcrest/HCBaseMatcher.h>
@interface HCStringContainsInOrder : HCBaseMatcher
{
NSArray *substrings;
}
+ (id)containsInOrder:(NSArray *)substringList;
- (id)initWithSubstrings:(NSArray *)substringList;
@end
OBJC_EXPORT id<HCMatcher> HC_stringContainsInOrder(NSString *substring, ...) NS_REQUIRES_NIL_TERMINATION;
/**
stringContainsInOrder(firstString, ...) -
Matches if object is a string containing a given list of substrings in relative order.
@param firstString,... A comma-separated list of strings ending with @c nil.
This matcher first checks whether the evaluated object is a string. If so, it checks whether it
contains a given list of strings, in relative order to each other. The searches are performed
starting from the beginning of the evaluated string.
Example:
@par
@ref stringContainsInOrder(@"bc", @"fg", @"jkl", nil)
will match "abcdefghijklm".
(In the event of a name clash, don't \#define @c HC_SHORTHAND and use the synonym
@c HC_stringContainsInOrder instead.)
@ingroup text_matchers
*/
#ifdef HC_SHORTHAND
#define stringContainsInOrder HC_stringContainsInOrder
#endif
@@ -0,0 +1,85 @@
//
// OCHamcrest - HCStringContainsInOrder.m
// Copyright 2012 hamcrest.org. See LICENSE.txt
//
// Created by: Jon Reid, http://qualitycoding.org/
// Docs: http://hamcrest.github.com/OCHamcrest/
// Source: https://github.com/hamcrest/OCHamcrest
//
#import "HCStringContainsInOrder.h"
#import "HCDescription.h"
@implementation HCStringContainsInOrder
+ (id)containsInOrder:(NSArray *)substringList
{
return [[self alloc] initWithSubstrings:substringList];
}
- (id)initWithSubstrings:(NSArray *)substringList
{
self = [super init];
if (self)
{
for (id substring in substringList)
{
if (![substring isKindOfClass:[NSString class]])
{
@throw [NSException exceptionWithName:@"NotAString"
reason:@"Arguments must be strings"
userInfo:nil];
}
}
substrings = substringList;
}
return self;
}
- (BOOL)matches:(id)item
{
if (![item isKindOfClass:[NSString class]])
return NO;
NSRange searchRange = NSMakeRange(0, [item length]);
for (NSString *substring in substrings)
{
NSRange substringRange = [item rangeOfString:substring options:0 range:searchRange];
if (substringRange.location == NSNotFound)
return NO;
searchRange.location = substringRange.location + substringRange.length;
searchRange.length = [item length] - searchRange.location;
}
return YES;
}
- (void)describeTo:(id<HCDescription>)description
{
[description appendList:substrings start:@"a string containing " separator:@", " end:@" in order"];
}
@end
#pragma mark -
id<HCMatcher> HC_stringContainsInOrder(NSString *substring, ...)
{
va_list args;
va_start(args, substring);
NSMutableArray *substringList = [NSMutableArray arrayWithObject:substring];
substring = va_arg(args, NSString *);
while (substring != nil)
{
[substringList addObject:substring];
substring = va_arg(args, NSString *);
}
va_end(args);
return [HCStringContainsInOrder containsInOrder:substringList];
}
@@ -0,0 +1,45 @@
//
// OCHamcrest - HCStringEndsWith.h
// Copyright 2012 hamcrest.org. See LICENSE.txt
//
// Created by: Jon Reid, http://qualitycoding.org/
// Docs: http://hamcrest.github.com/OCHamcrest/
// Source: https://github.com/hamcrest/OCHamcrest
//
#import <OCHamcrest/HCSubstringMatcher.h>
@interface HCStringEndsWith : HCSubstringMatcher
+ (id)stringEndsWith:(NSString *)aSubstring;
@end
OBJC_EXPORT id<HCMatcher> HC_endsWith(NSString *aSubstring);
/**
endsWith(aString) -
Matches if object is a string ending with a given string.
@param aString The string to search for. This value must not be @c nil.
This matcher first checks whether the evaluated object is a string. If so, it checks if
@a aString matches the ending characters of the evaluated object.
Example:
@par
@ref endsWith(@"bar")
will match "foobar".
(In the event of a name clash, don't \#define @c HC_SHORTHAND and use the synonym
@c HC_endsWith instead.)
@ingroup text_matchers
*/
#ifdef HC_SHORTHAND
#define endsWith HC_endsWith
#endif
@@ -0,0 +1,41 @@
//
// OCHamcrest - HCStringEndsWith.m
// Copyright 2012 hamcrest.org. See LICENSE.txt
//
// Created by: Jon Reid, http://qualitycoding.org/
// Docs: http://hamcrest.github.com/OCHamcrest/
// Source: https://github.com/hamcrest/OCHamcrest
//
#import "HCStringEndsWith.h"
@implementation HCStringEndsWith
+ (id)stringEndsWith:(NSString *)aString
{
return [[self alloc] initWithSubstring:aString];
}
- (BOOL)matches:(id)item
{
if (![item respondsToSelector:@selector(hasSuffix:)])
return NO;
return [item hasSuffix:substring];
}
- (NSString *)relationship
{
return @"ending with";
}
@end
#pragma mark -
id<HCMatcher> HC_endsWith(NSString *aString)
{
return [HCStringEndsWith stringEndsWith:aString];
}
@@ -0,0 +1,45 @@
//
// OCHamcrest - HCStringStartsWith.h
// Copyright 2012 hamcrest.org. See LICENSE.txt
//
// Created by: Jon Reid, http://qualitycoding.org/
// Docs: http://hamcrest.github.com/OCHamcrest/
// Source: https://github.com/hamcrest/OCHamcrest
//
#import <OCHamcrest/HCSubstringMatcher.h>
@interface HCStringStartsWith : HCSubstringMatcher
+ (id)stringStartsWith:(NSString *)aSubstring;
@end
OBJC_EXPORT id<HCMatcher> HC_startsWith(NSString *aSubstring);
/**
startsWith(aString) -
Matches if object is a string starting with a given string.
@param aString The string to search for. This value must not be @c nil.
This matcher first checks whether the evaluated object is a string. If so, it checks if
@a aString matches the beginning characters of the evaluated object.
Example:
@par
@ref endsWith(@"foo")
will match "foobar".
(In the event of a name clash, don't \#define @c HC_SHORTHAND and use the synonym
@c HC_startsWith instead.)
@ingroup text_matchers
*/
#ifdef HC_SHORTHAND
#define startsWith HC_startsWith
#endif
@@ -0,0 +1,41 @@
//
// OCHamcrest - HCStringStartsWith.m
// Copyright 2012 hamcrest.org. See LICENSE.txt
//
// Created by: Jon Reid, http://qualitycoding.org/
// Docs: http://hamcrest.github.com/OCHamcrest/
// Source: https://github.com/hamcrest/OCHamcrest
//
#import "HCStringStartsWith.h"
@implementation HCStringStartsWith
+ (id)stringStartsWith:(NSString *)aSubstring
{
return [[self alloc] initWithSubstring:aSubstring];
}
- (BOOL)matches:(id)item
{
if (![item respondsToSelector:@selector(hasPrefix:)])
return NO;
return [item hasPrefix:substring];
}
- (NSString *)relationship
{
return @"starting with";
}
@end
#pragma mark -
id<HCMatcher> HC_startsWith(NSString *aString)
{
return [HCStringStartsWith stringStartsWith:aString];
}
@@ -0,0 +1,20 @@
//
// OCHamcrest - HCSubstringMatcher.h
// Copyright 2012 hamcrest.org. See LICENSE.txt
//
// Created by: Jon Reid, http://qualitycoding.org/
// Docs: http://hamcrest.github.com/OCHamcrest/
// Source: https://github.com/hamcrest/OCHamcrest
//
#import <OCHamcrest/HCBaseMatcher.h>
@interface HCSubstringMatcher : HCBaseMatcher
{
NSString *substring;
}
- (id)initWithSubstring:(NSString *)aString;
@end
@@ -0,0 +1,41 @@
//
// OCHamcrest - HCSubstringMatcher.m
// Copyright 2012 hamcrest.org. See LICENSE.txt
//
// Created by: Jon Reid, http://qualitycoding.org/
// Docs: http://hamcrest.github.com/OCHamcrest/
// Source: https://github.com/hamcrest/OCHamcrest
//
#import "HCSubstringMatcher.h"
#import "HCDescription.h"
#import "HCRequireNonNilObject.h"
@interface HCSubstringMatcher (SubclassResponsibility)
- (NSString *)relationship;
@end
@implementation HCSubstringMatcher
- (id)initWithSubstring:(NSString *)aString
{
HCRequireNonNilObject(aString);
self = [super init];
if (self)
substring = [aString copy];
return self;
}
- (void)describeTo:(id<HCDescription>)description
{
[[[[description appendText:@"a string "]
appendText:[self relationship]]
appendText:@" "]
appendDescriptionOf:substring];
}
@end
@@ -0,0 +1,216 @@
//
// OCHamcrest - MainPage.h
// Copyright 2012 hamcrest.org. See LICENSE.txt
//
// Created by: Jon Reid, http://qualitycoding.org/
// Docs: http://hamcrest.github.com/OCHamcrest/
// Source: https://github.com/hamcrest/OCHamcrest
//
/**
@mainpage OCHamcrest
@section contents Contents:
@li @ref whatisit
@li @ref addtoproject
@li @ref firsttest
@li @ref predefined
@li @ref sugar
@li @ref custom
@li @ref resources
@section whatisit What is OCHamcrest?
OCHamcrest is:
@li a library of "matcher" objects that let you declare rules for whether a given object matches
the criteria or not.
@li a framework for writing your own matchers.
Matchers are useful for a variety of purposes, such as UI validation. But they're most commonly
used for writing unit tests that are expressive and flexible.
OCHamcrest is used for both Mac and iOS development with:
@li OCUnit (SenTestingKit) built in to Xcode
@li Google Toolbox for Mac (GTM)
@li GHUnit
@li Cedar BDD framework
@li OCMock
@li OCMockito
@section addtoproject How do I add OCHamcrest to my project?
@b Building:
If you want to build OCHamcrest yourself, cd to the Source folder, then
@code
$ ./MakeDistribution.sh
@endcode
Or just use the pre-built release available in
<a href="https://github.com/hamcrest/OCHamcrest/downloads">Downloads</a>.
@b Mac Project Setup:
Add OCHamcrest.framework to your project.
Add a Copy Files build phase to copy OCHamcrest.framework to your Products Directory. For
unit test bundles, make sure this Copy Files phase comes before the Run Script phase that
executes tests.
Add:
@code
#define HC_SHORTHAND
#import <OCHamcrest/OCHamcrest.h>
@endcode
Note: If your Console shows @code
otest[57510:203] *** NSTask: Task create for path '...' failed: 22, "Invalid argument". Terminating temporary process.
@endcode
double-check your Copy Files phase.
@b iOS Project Setup:
Add OCHamcrestIOS.framework to your project.
Add:
@code
#define HC_SHORTHAND
#import <OCHamcrestIOS/OCHamcrestIOS.h>
@endcode
@section firsttest My first OCHamcrest test
We'll start by writing a very simple Xcode unit test, but instead of using OCUnit's
@c STAssertEqualObjects function, we'll use OCHamcrest's @c assertThat construct and a
predefined matcher:
@code
#import <SenTestingKit/SenTestingKit.h>
#define HC_SHORTHAND
#import <OCHamcrest/OCHamcrest.h>
@interface BiscuitTest : SenTestCase
@end
@implementation BiscuitTest
- (void)testEquals
{
Biscuit* theBiscuit = [Biscuit biscuitNamed:@"Ginger"];
Biscuit* myBiscuit = [Biscuit biscuitNamed:@"Ginger"];
assertThat(theBiscuit, equalTo(myBiscuit));
}
@end
@endcode
The @ref assertThat function is a stylized sentence for making a test assertion. In this
example, the subject of the assertion is the object @c theBiscuit, which is the first method
parameter. The second method parameter is a matcher for @c Biscuit objects, here a matcher that
checks one object is equal to another using the @c -isEqual: method. The test passes since the
@c Biscuit class defines an @c -isEqual: method.
OCHamcrest's functions are actually declared with an "HC" package prefix (such as
@c HC_assertThat and @c HC_equalTo) to avoid name clashes. To make test writing faster and test
code more legible, shorthand macros are provided if @c HC_SHORTHAND is defined before including
the OCHamcrest header. For example, instead of writing @ref HC_assertThat, simply write
@ref assertThat.
@section predefined Predefined matchers
OCHamcrest comes with a library of useful matchers:
<ul>
<li>Object</li>
<ul>
<li>@ref conformsTo - match object that conforms to protocol</li>
<li>@ref equalTo - match equal object</li>
<li>@ref hasDescription - match object's @c -description</li>
<li>@ref hasProperty - match return value of method with given name</li>
<li>@ref instanceOf - match object type</li>
<li>@ref nilValue, @ref notNilValue - match @c nil, or not @c nil</li>
<li>@ref sameInstance - match same object</li>
</ul>
<li>Number</li>
<ul>
<li>@ref closeTo - match number close to a given value</li>
<li>@b equalTo&lt;TypeName&gt; - match number equal to a primitive number (such as @ref equalToInt for an @c int)</li>
<li>@ref greaterThan, @ref greaterThanOrEqualTo, @ref lessThan, @ref lessThanOrEqualTo - match numeric ordering</li>
</ul>
<li>Text</li>
<ul>
<li>@ref containsString - match part of a string</li>
<li>@ref endsWith - match the end of a string</li>
<li>@ref equalToIgnoringCase - match the complete string but ignore case</li>
<li>@ref equalToIgnoringWhitespace - match the complete string but ignore extra whitespace</li>
<li>@ref startsWith - match the beginning of a string</li>
<li>@ref stringContainsInOrder - match parts of a string, in relative order</li>
</ul>
<li>Logical</li>
<ul>
<li>@ref allOf - "and" together all matchers</li>
<li>@ref anyOf - "or" together all matchers</li>
<li>@ref anything - match anything (useful in composite matchers when you don't care about a particular value)</li>
<li>@ref isNot - negate the matcher</li>
</ul>
<li>Collection</li>
<ul>
<li>@ref contains - exactly match the entire collection</li>
<li>@ref containsInAnyOrder - match the entire collection, but in any order</li>
<li>@ref empty - match empty collection</li>
<li>@ref hasCount - match number of elements against another matcher</li>
<li>@ref hasCountOf - match collection with given number of elements</li>
<li>@ref hasEntries - match dictionary with list of key-value pairs</li>
<li>@ref hasEntry - match dictionary containing a key-value pair</li>
<li>@ref hasItem - match if given item appears in the collection</li>
<li>@ref hasItems - match if all given items appears in the collection, in any order</li>
<li>@ref hasKey - match dictionary with a key</li>
<li>@ref hasValue - match dictionary with a value</li>
<li>@ref onlyContains - match if collection's items appear in given list</li>
</ul>
<li>Decorator</li>
<ul>
<li>@ref describedAs - give the matcher a custom failure description</li>
<li>@ref is - decorator to improve readability - see @ref sugar, below</li>
</ul>
</ul>
The arguments for many of these matchers accept not just a matching value, but another matcher,
so matchers can be composed for greater flexibility. For example,
<tt>only_contains(endsWith(\@"."))</tt> will match any collection where every item is a string
ending with period.
@section sugar Syntactic sugar
OCHamcrest strives to make your tests as readable as possible. For example, the @ref is matcher
is a wrapper that doesn't add any extra behavior to the underlying matcher. The following
assertions are all equivalent:
@code
assertThat(theBiscuit, equalTo(myBiscuit));
assertThat(theBiscuit, is(equalTo(myBiscuit)));
assertThat(theBiscuit, is(myBiscuit));
@endcode
@section custom Writing custom matchers
A key feature of OCHamcrest is its extensibility. See @ref custom-matchers for an example of how
to write your own matchers.
@section resources More resources
@li <a href="https://github.com/hamcrest/OCHamcrest">Sources</a>
@li <a href="http://hamcrest.org/">Hamcrest</a>
@li <a href="http://qualitycoding.org/">Quality Coding</a> - Tools, tips &amp; techniques for
<em>building quality in</em> to iOS development
*/
+57
View File
@@ -0,0 +1,57 @@
VERSION=1.9
DISTFILE=OCHamcrest-${VERSION}
DISTPATH=build/${DISTFILE}
PROJECTROOT=..
DOCSET=build/Documentation/org.hamcrest.OCHamcrest.docset
echo Preparing clean build
rm -rf build
mkdir build
echo Building OCHamcrest - Release
xcodebuild -configuration Release -target OCHamcrest
OUT=$?
if [ "${OUT}" -ne "0" ]; then
echo OCHamcrest release build failed
exit ${OUT}
fi
echo Building OCHamcrestIOS - Release
source MakeIOSFramework.sh
OUT=$?
if [ "${OUT}" -ne "0" ]; then
echo OCHamcrestIOS release build failed
exit ${OUT}
fi
echo Building Documentation
source MakeDocumentation.sh
echo Assembling Distribution
rm -rf "${DISTPATH}"
mkdir "${DISTPATH}"
cp -R "build/Release/OCHamcrest.framework" "${DISTPATH}"
cp -R "build/Release/OCHamcrestIOS.framework" "${DISTPATH}"
cp "${PROJECTROOT}/README.md" "${DISTPATH}"
cp "${PROJECTROOT}/CHANGES.txt" "${DISTPATH}"
cp "${PROJECTROOT}/LICENSE.txt" "${DISTPATH}"
cp -R "${PROJECTROOT}/Examples" "${DISTPATH}"
mkdir "${DISTPATH}/Documentation"
cp -R "${DOCSET}" "${DISTPATH}/Documentation"
cp "${PROJECTROOT}/Documentation/Makefile" "${DISTPATH}/Documentation"
cp "${PROJECTROOT}/Documentation/README.txt" "${DISTPATH}/Documentation"
find "${DISTPATH}/Examples" -type d \( -name 'build' -or -name 'xcuserdata' -or -name '.svn' -or -name '.git' \) | while read DIR
do
rm -R "${DIR}";
done
find "${DISTPATH}/Examples" -type f \( -name '*.pbxuser' -or -name '*.perspectivev3' -or -name '*.mode1v3' -or -name '.DS_Store' -or -name '.gitignore' \) | while read FILE
do
rm "${FILE}";
done
pushd build
zip --recurse-paths --symlinks ${DISTFILE}.zip ${DISTFILE}
open .
popd
+13
View File
@@ -0,0 +1,13 @@
DOXYGEN=/Applications/Doxygen.app/Contents/Resources/doxygen
if ! [ -f $DOXYGEN ]; then
echo :: error : Requires Doxygen in Applications folder
exit 1
fi
$DOXYGEN "../Documentation/Doxyfile"
# Generate Xcode documentation set
pushd build/Documentation
make
popd
+48
View File
@@ -0,0 +1,48 @@
# First build the OS X framework to get its folder structure.
xcodebuild -configuration Release -target OCHamcrest -sdk macosx
# We'll copy the OS X framework to a new location, then modify it in place.
OSX_FRAMEWORK="build/Release/OCHamcrest.framework/"
IOS_FRAMEWORK="build/Release/OCHamcrestIOS.framework/"
# Trigger builds of the static library for both the simulator and the device.
xcodebuild -configuration Release -target libochamcrest -sdk iphoneos
OUT=$?
if [ "${OUT}" -ne "0" ]; then
echo Device build failed
exit ${OUT}
fi
xcodebuild -configuration Release -target libochamcrest -sdk iphonesimulator
OUT=$?
if [ "${OUT}" -ne "0" ]; then
echo Simulator build failed
exit ${OUT}
fi
# Copy the OS X framework to the new location.
mkdir -p "${IOS_FRAMEWORK}"
rsync -q -a --delete "${OSX_FRAMEWORK}" "${IOS_FRAMEWORK}"
# Rename the main header.
mv "${IOS_FRAMEWORK}/Headers/OCHamcrest.h" "${IOS_FRAMEWORK}/Headers/OCHamcrestIOS.h"
# Update all imports to use the new framework name.
IMPORT_EXPRESSION="s/#import <OCHamcrest/#import <OCHamcrestIOS/g;"
find "${IOS_FRAMEWORK}" -name '*.h' -print0 | xargs -0 perl -pi -e "${IMPORT_EXPRESSION}"
# Delete the existing (OS X) library and the link to it.
rm "${IOS_FRAMEWORK}/OCHamcrest" "${IOS_FRAMEWORK}/Versions/Current/OCHamcrest"
# Create a new library that is a fat library containing both static libraries.
DEVICE_LIB="build/Release-iphoneos/libochamcrest.a"
SIMULATOR_LIB="build/Release-iphonesimulator/libochamcrest.a"
OUTPUT_LIB="${IOS_FRAMEWORK}/Versions/Current/OCHamcrestIOS"
lipo -create "${DEVICE_LIB}" -arch i386 "${SIMULATOR_LIB}" -o "${OUTPUT_LIB}"
# Add a symlink, as required by the framework.
ln -s Versions/Current/OCHamcrestIOS "${IOS_FRAMEWORK}/OCHamcrestIOS"
# Update the name in the plist file.
NAME_EXPRESSION="s/OCHamcrest/OCHamcrestIOS/g;"
perl -pi -e "${NAME_EXPRESSION}" "${IOS_FRAMEWORK}/Resources/Info.plist"
@@ -0,0 +1,30 @@
<?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>CFBundleIconFile</key>
<string></string>
<key>CFBundleIdentifier</key>
<string>org.hamcrest.${PRODUCT_NAME}</string>
<key>CFBundleInfoDictionaryVersion</key>
<string>6.0</string>
<key>CFBundleName</key>
<string>${PRODUCT_NAME}</string>
<key>CFBundlePackageType</key>
<string>FMWK</string>
<key>CFBundleShortVersionString</key>
<string>1.9</string>
<key>CFBundleSignature</key>
<string>????</string>
<key>CFBundleVersion</key>
<string>1.9</string>
<key>NSHumanReadableCopyright</key>
<string>Copyright © 2012 hamcrest.org</string>
<key>NSPrincipalClass</key>
<string></string>
</dict>
</plist>
@@ -0,0 +1,10 @@
//
// Prefix header for all source files of the 'OCHamcrest' target in the 'OCHamcrest' project.
//
#ifdef __OBJC__
#import <Foundation/Foundation.h>
#import <objc/objc-api.h>
#endif
@@ -0,0 +1,137 @@
//
// OCHamcrest - OCHamcrest.h
// Copyright 2012 hamcrest.org. See LICENSE.txt
//
// Created by: Jon Reid, http://qualitycoding.org/
// Docs: http://hamcrest.github.com/OCHamcrest/
// Source: https://github.com/hamcrest/OCHamcrest
//
/**
@defgroup library Matcher Library
Library of Matcher implementations.
*/
/**
@defgroup object_matchers Object Matchers
Matchers that inspect objects.
@ingroup library
*/
#import <OCHamcrest/HCConformsToProtocol.h>
#import <OCHamcrest/HCHasDescription.h>
#import <OCHamcrest/HCHasProperty.h>
#import <OCHamcrest/HCIsEqual.h>
#import <OCHamcrest/HCIsInstanceOf.h>
#import <OCHamcrest/HCIsNil.h>
#import <OCHamcrest/HCIsSame.h>
/**
@defgroup collection_matchers Collection Matchers
Matchers of collections.
@ingroup library
*/
#import <OCHamcrest/HCHasCount.h>
#import <OCHamcrest/HCIsCollectionContaining.h>
#import <OCHamcrest/HCIsCollectionContainingInAnyOrder.h>
#import <OCHamcrest/HCIsCollectionContainingInOrder.h>
#import <OCHamcrest/HCIsCollectionOnlyContaining.h>
#import <OCHamcrest/HCIsDictionaryContaining.h>
#import <OCHamcrest/HCIsDictionaryContainingEntries.h>
#import <OCHamcrest/HCIsDictionaryContainingKey.h>
#import <OCHamcrest/HCIsDictionaryContainingValue.h>
#import <OCHamcrest/HCIsEmptyCollection.h>
#import <OCHamcrest/HCIsIn.h>
/**
@defgroup number_matchers Number Matchers
Matchers that perform numeric comparisons.
@ingroup library
*/
#import <OCHamcrest/HCIsCloseTo.h>
#import <OCHamcrest/HCOrderingComparison.h>
/**
@defgroup primitive_number_matchers Primitive Number Matchers
Matchers for testing equality against primitive numeric types.
@ingroup number_matchers
*/
#import <OCHamcrest/HCIsEqualToNumber.h>
/**
@defgroup text_matchers Text Matchers
Matchers that perform text comparisons.
@ingroup library
*/
#import <OCHamcrest/HCIsEqualIgnoringCase.h>
#import <OCHamcrest/HCIsEqualIgnoringWhiteSpace.h>
#import <OCHamcrest/HCStringContains.h>
#import <OCHamcrest/HCStringContainsInOrder.h>
#import <OCHamcrest/HCStringEndsWith.h>
#import <OCHamcrest/HCStringStartsWith.h>
/**
@defgroup logical_matchers Logical Matchers
Boolean logic using other matchers.
@ingroup library
*/
#import <OCHamcrest/HCAllOf.h>
#import <OCHamcrest/HCAnyOf.h>
#import <OCHamcrest/HCIsAnything.h>
#import <OCHamcrest/HCIsNot.h>
/**
@defgroup decorator_matchers Decorator Matchers
Matchers that decorate other matchers for better expression.
@ingroup library
*/
#import <OCHamcrest/HCDescribedAs.h>
#import <OCHamcrest/HCIs.h>
/**
@defgroup integration Unit Test Integration
*/
#import <OCHamcrest/HCAssertThat.h>
/**
@defgroup integration_numeric Unit Tests of Primitive Numbers
Unit test integration for primitive numbers.
The @c assertThat&lt;Type&gt; macros convert the primitive actual value to an @c NSNumber,
passing that to the matcher for evaluation. If the matcher is not satisfied, an exception is
thrown describing the mismatch.
This family of macros is designed to integrate well with OCUnit and other unit testing
frameworks. Unmet assertions are reported as test failures. In Xcode, they can be clicked to
reveal the line of the assertion.
@ingroup integration
*/
#import <OCHamcrest/HCNumberAssert.h>
/**
@defgroup core Core API
*/
/**
@defgroup helpers Helpers
Utilities for writing Matchers.
@ingroup core
*/
Loaded 100 of 1261 files, more files were not shown because too many files have changed in this diff. Show more