Skip to content
This repository has been archived by the owner on Dec 2, 2019. It is now read-only.

Commit

Permalink
Merge pull request #5 from github/merge-upstream
Browse files Browse the repository at this point in the history
Merge upstream
  • Loading branch information
joshaber committed Jul 25, 2013
2 parents e767c8c + 35540a6 commit dc270cf
Show file tree
Hide file tree
Showing 12 changed files with 127 additions and 44 deletions.
14 changes: 14 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,17 @@
v0.2.2
======

* Trigger a memory barrier when using `will` [jspahrsummers]
* Support for ARC when writing custom matchers [nickhutchinson]
* Ensure matcher category loading with constructors [robrix]
* haveCountOf supports any class that responds to `count` [segiddins][apparentsoft]

v0.2.1
======

* Added raiseWithReason matcher [blakewatters]
* Fixed crash when expecting a block [chrisdevereux]

v0.2.0
======

Expand Down
4 changes: 2 additions & 2 deletions Expecta.podspec
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
Pod::Spec.new do |s|
s.name = 'Expecta'
s.version = '0.2.1'
s.version = '0.2.2'
s.license = 'MIT'
s.summary = 'A matcher framework for Objective-C & Cocoa.'
s.homepage = 'http://github.com/petejkim/expecta'
s.author = { 'Peter Jihoon Kim' => 'raingrove@gmail.com' }

s.source = { :git => 'https://github.com/petejkim/expecta.git', :tag => 'v0.2.1' }
s.source = { :git => 'https://github.com/specta/expecta.git', :tag => 'v0.2.2' }

s.description = %{
Expecta is a matcher framework for Objective-C and Cocoa. The main
Expand Down
20 changes: 8 additions & 12 deletions Expecta.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,8 @@
objects = {

/* Begin PBXBuildFile section */
2546A95C16629D500078E044 /* EXPMatchers+raiseWithReason.h in Headers */ = {isa = PBXBuildFile; fileRef = 2546A95A16629D4F0078E044 /* EXPMatchers+raiseWithReason.h */; };
2546A95D16629D500078E044 /* EXPMatchers+raiseWithReason.h in Headers */ = {isa = PBXBuildFile; fileRef = 2546A95A16629D4F0078E044 /* EXPMatchers+raiseWithReason.h */; };
2546A95C16629D500078E044 /* EXPMatchers+raiseWithReason.h in Headers */ = {isa = PBXBuildFile; fileRef = 2546A95A16629D4F0078E044 /* EXPMatchers+raiseWithReason.h */; settings = {ATTRIBUTES = (Public, ); }; };
2546A95D16629D500078E044 /* EXPMatchers+raiseWithReason.h in Headers */ = {isa = PBXBuildFile; fileRef = 2546A95A16629D4F0078E044 /* EXPMatchers+raiseWithReason.h */; settings = {ATTRIBUTES = (Public, ); }; };
2546A95E16629D500078E044 /* EXPMatchers+raiseWithReason.m in Sources */ = {isa = PBXBuildFile; fileRef = 2546A95B16629D4F0078E044 /* EXPMatchers+raiseWithReason.m */; };
2546A95F16629D500078E044 /* EXPMatchers+raiseWithReason.m in Sources */ = {isa = PBXBuildFile; fileRef = 2546A95B16629D4F0078E044 /* EXPMatchers+raiseWithReason.m */; };
2546A96216629DF70078E044 /* EXPMatchers+raiseWithReasonTest.m in Sources */ = {isa = PBXBuildFile; fileRef = 2546A96116629DF70078E044 /* EXPMatchers+raiseWithReasonTest.m */; };
Expand Down Expand Up @@ -361,14 +361,14 @@
E9ACDF0113B2DD520010F4D7 = {
isa = PBXGroup;
children = (
E95368421521B5FC00AA3B81 /* Expecta.podspec */,
E9ACDF9413B2DEF30010F4D7 /* LICENSE */,
E9ACDF9513B2DEF30010F4D7 /* README.md */,
E9A6BAAE13B7183100950250 /* RDD.md */,
E9ACDF3C13B2DDB00010F4D7 /* src */,
E9ACDF7213B2DEB70010F4D7 /* test */,
E9ACDF0E13B2DD520010F4D7 /* frameworks */,
E9ACDF0D13B2DD520010F4D7 /* products */,
E95368421521B5FC00AA3B81 /* Expecta.podspec */,
E9ACDF9413B2DEF30010F4D7 /* LICENSE */,
E9ACDF9513B2DEF30010F4D7 /* README.md */,
E9A6BAAE13B7183100950250 /* RDD.md */,
);
sourceTree = "<group>";
};
Expand Down Expand Up @@ -583,11 +583,11 @@
63F6F356150A542D009E1BC3 /* EXPMatchers+beCloseTo.h in Headers */,
63B349DE15135C8800C955DC /* EXPMatchers+haveCountOf.h in Headers */,
E9D3DF16157A7EB40054978E /* EXPMatchers+raise.h in Headers */,
2546A95D16629D500078E044 /* EXPMatchers+raiseWithReason.h in Headers */,
A305755F1520BCCB00DA19BD /* EXPMatcher.h in Headers */,
A30575641520BDCE00DA19BD /* EXPBlockDefinedMatcher.h in Headers */,
E95368521521BEE900AA3B81 /* EXPBackwardCompatibility.h in Headers */,
E95368911521C58D00AA3B81 /* EXPDefines.h in Headers */,
2546A95D16629D500078E044 /* EXPMatchers+raiseWithReason.h in Headers */,
);
runOnlyForDeploymentPostprocessing = 0;
};
Expand Down Expand Up @@ -622,11 +622,11 @@
63F6F355150A542D009E1BC3 /* EXPMatchers+beCloseTo.h in Headers */,
63B349DD15135C8800C955DC /* EXPMatchers+haveCountOf.h in Headers */,
E9D3DF15157A7EB40054978E /* EXPMatchers+raise.h in Headers */,
2546A95C16629D500078E044 /* EXPMatchers+raiseWithReason.h in Headers */,
A305755E1520BCCB00DA19BD /* EXPMatcher.h in Headers */,
A30575631520BDCE00DA19BD /* EXPBlockDefinedMatcher.h in Headers */,
E95368511521BEE900AA3B81 /* EXPBackwardCompatibility.h in Headers */,
E95368921521C58D00AA3B81 /* EXPDefines.h in Headers */,
2546A95C16629D500078E044 /* EXPMatchers+raiseWithReason.h in Headers */,
);
runOnlyForDeploymentPostprocessing = 0;
};
Expand Down Expand Up @@ -1054,7 +1054,6 @@
DSTROOT = /tmp/Expecta_iOS.dst;
GCC_PRECOMPILE_PREFIX_HEADER = YES;
GCC_PREFIX_HEADER = "src/Expecta-Prefix.pch";
GCC_VERSION = com.apple.compilers.llvm.clang.1_0;
IPHONEOS_DEPLOYMENT_TARGET = 4.0;
PRIVATE_HEADERS_FOLDER_PATH = "";
PRODUCT_NAME = "$(TARGET_NAME)";
Expand All @@ -1072,7 +1071,6 @@
DSTROOT = /tmp/Expecta_iOS.dst;
GCC_PRECOMPILE_PREFIX_HEADER = YES;
GCC_PREFIX_HEADER = "src/Expecta-Prefix.pch";
GCC_VERSION = com.apple.compilers.llvm.clang.1_0;
IPHONEOS_DEPLOYMENT_TARGET = 4.0;
PRIVATE_HEADERS_FOLDER_PATH = "";
PRODUCT_NAME = "$(TARGET_NAME)";
Expand Down Expand Up @@ -1193,7 +1191,6 @@
GCC_ENABLE_OBJC_EXCEPTIONS = YES;
GCC_PRECOMPILE_PREFIX_HEADER = YES;
GCC_PREFIX_HEADER = "src/Expecta-Prefix.pch";
GCC_VERSION = com.apple.compilers.llvm.clang.1_0;
PRIVATE_HEADERS_FOLDER_PATH = "";
PRODUCT_NAME = "$(TARGET_NAME)";
PUBLIC_HEADERS_FOLDER_PATH = "";
Expand All @@ -1208,7 +1205,6 @@
GCC_ENABLE_OBJC_EXCEPTIONS = YES;
GCC_PRECOMPILE_PREFIX_HEADER = YES;
GCC_PREFIX_HEADER = "src/Expecta-Prefix.pch";
GCC_VERSION = com.apple.compilers.llvm.clang.1_0;
PRIVATE_HEADERS_FOLDER_PATH = "";
PRODUCT_NAME = "$(TARGET_NAME)";
PUBLIC_HEADERS_FOLDER_PATH = "";
Expand Down
2 changes: 1 addition & 1 deletion LICENSE
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
Copyright (c) 2011-2012 Peter Jihoon Kim and contributors
Copyright (c) 2011-2012 Specta Team - https://github.com/specta

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
Expand Down
30 changes: 24 additions & 6 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -35,8 +35,14 @@ expect(baz).to.equal(3.14159);
Use [CocoaPods](https://github.com/CocoaPods/CocoaPods)

```ruby
dependency 'Expecta', '~> 0.2.1'
# dependency 'Specta', '~> 0.1.7' # specta bdd framework
target :MyApp do
# your app dependencies
end

target :MyAppTests do
pod 'Expecta', '~> 0.2.2' # expecta matchers
# pod 'Specta', '~> 0.1.11' # specta bdd framework
end
```

or
Expand Down Expand Up @@ -224,16 +230,28 @@ You can find the public Tracker project [here](https://www.pivotaltracker.com/pr
* Please prefix instance variable names with a single underscore (`_`).
* Please prefix custom classes and functions defined in the global scope with `EXP`.
## CREDITS
Expecta is brought to you by [Peter Jihoon Kim](http://github.com/petejkim) and the [Specta team](https://github.com/specta?tab=members).
### CONTRIBUTORS
* [Kurtis Seebaldt](https://github.com/kseebaldt)
* [Alan Rogers](https://github.com/alanjrogers)
* [Andrew Kitchen](https://github.com/akitchen)
* [Jon Cooper](https://github.com/joncooper)
* [Blake Watters](https://github.com/blakewatters)
* [Christopher Pickslay](https://github.com/twobitlabs)
* [Chris Devereux](https://github.com/chrisdevereux)
* [David Hart](https://github.com/TrahDivad)
* [Jacob Gorban](https://github.com/apparentsoft)
* [Jon Cooper](https://github.com/joncooper)
* [Justin Spahr-Summers](https://github.com/jspahrsummers)
* [Kurtis Seebaldt](https://github.com/kseebaldt)
* [Luke Redpath](https://github.com/lukeredpath)
* [Nicholas Hutchinson](https://github.com/nickhutchinson)
* [Rob Rix](https://github.com/robrix)
* [Samuel Giddins](https://github.com/segiddins)
* [Zack Waugh](https://github.com/zachwaugh)
## LICENSE
Copyright (c) 2011-2012 Peter Jihoon Kim and contributors. This software is licensed under the [MIT License](http://github.com/petejkim/expecta/raw/master/LICENSE).
Expecta is licensed under the [MIT License](http://github.com/petejkim/expecta/raw/master/LICENSE).
10 changes: 10 additions & 0 deletions src/EXPBlockDefinedMatcher.m
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,16 @@

@implementation EXPBlockDefinedMatcher

- (void)dealloc
{
self.prerequisiteBlock = nil;
self.matchBlock = nil;
self.failureMessageForToBlock = nil;
self.failureMessageForNotToBlock = nil;

[super dealloc];
}

@synthesize prerequisiteBlock;
@synthesize matchBlock;
@synthesize failureMessageForToBlock;
Expand Down
10 changes: 8 additions & 2 deletions src/EXPExpect.m
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,12 @@ - (id)initWithActualBlock:(id)actualBlock testCase:(id)testCase lineNumber:(int)
return self;
}

- (void)dealloc
{
self.actualBlock = nil;
[super dealloc];
}

+ (EXPExpect *)expectWithActualBlock:(id)actualBlock testCase:(id)testCase lineNumber:(int)lineNumber fileName:(char *)fileName {
return [[[EXPExpect alloc] initWithActualBlock:actualBlock testCase:(id)testCase lineNumber:lineNumber fileName:fileName] autorelease];
}
Expand Down Expand Up @@ -186,9 +192,9 @@ - (NSString *)failureMessageForNotTo:(id)actual
{
__block id blockExpectation = _expectation;

return [^{
return [[^{
[blockExpectation applyMatcher:self];
} copy];
} copy] autorelease];
}

@end
19 changes: 14 additions & 5 deletions src/ExpectaSupport.h
Original file line number Diff line number Diff line change
Expand Up @@ -12,10 +12,18 @@ void EXP_match(EXPBoolBlock block);
void EXP_failureMessageForTo(EXPStringBlock block);
void EXP_failureMessageForNotTo(EXPStringBlock block);

#if __has_feature(objc_arc)
#define _EXP_release(x)
#define _EXP_autorelease(x) (x)

#else
#define _EXP_release(x) [x release]
#define _EXP_autorelease(x) [x autorelease]
#endif

// workaround for the categories bug: http://developer.apple.com/library/mac/#qa/qa1490/_index.html
#define EXPFixCategoriesBug(name) \
@interface EXPFixCategoriesBug##name : NSObject; @end \
@implementation EXPFixCategoriesBug##name; @end
__attribute__((constructor)) static void EXPFixCategoriesBug##name() {}

#define _EXPMatcherInterface(matcherName, matcherArguments) \
@interface EXPExpect (matcherName##Matcher) \
Expand All @@ -35,13 +43,14 @@ EXPFixCategoriesBug(EXPMatcher##matcherName##Matcher); \
__block void (^failureMessageForTo)(EXPStringBlock block) = ^(EXPStringBlock block) { EXP_failureMessageForTo(block); }; \
__block void (^failureMessageForNotTo)(EXPStringBlock block) = ^(EXPStringBlock block) { EXP_failureMessageForNotTo(block); }; \
prerequisite(nil); match(nil); failureMessageForTo(nil); failureMessageForNotTo(nil); \
void (^matcherBlock) matcherArguments = ^ matcherArguments { \
void (^matcherBlock) matcherArguments = [^ matcherArguments { \
{

#define _EXPMatcherImplementationEnd \
} \
[self applyMatcher:matcher to:&actual]; \
}; \
return [[matcherBlock copy] autorelease]; \
} copy]; \
_EXP_release(matcher); \
return _EXP_autorelease(matcherBlock); \
} \
@end
6 changes: 5 additions & 1 deletion src/ExpectaSupport.m
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,10 @@ id _EXPObjectify(char *type, ...) {
if(strcmp(type, @encode(char)) == 0) {
char actual = (char)va_arg(v, int);
obj = [NSNumber numberWithChar:actual];
} else if(strcmp(type, @encode(_Bool)) == 0) {
_Static_assert(sizeof(_Bool) <= sizeof(int), "Expected _Bool to be subject to vararg type promotion");
_Bool actual = (_Bool)va_arg(v, int);
obj = [NSNumber numberWithBool:actual];
} else if(strcmp(type, @encode(double)) == 0) {
double actual = (double)va_arg(v, double);
obj = [NSNumber numberWithDouble:actual];
Expand Down Expand Up @@ -135,7 +139,7 @@ void EXPFail(id testCase, int lineNumber, char *fileName, NSString *message) {
[arr addObject:EXPDescribeObject(o)];
}
description = [NSString stringWithFormat:@"(%@)", [arr componentsJoinedByString:@", "]];
} else if([obj isKindOfClass:[NSSet class]]) {
} else if([obj isKindOfClass:[NSSet class]] || [obj isKindOfClass:[NSOrderedSet class]]) {
NSMutableArray *arr = [NSMutableArray arrayWithCapacity:[obj count]];
for(id o in obj) {
[arr addObject:EXPDescribeObject(o)];
Expand Down
13 changes: 5 additions & 8 deletions src/matchers/EXPMatchers+haveCountOf.m
Original file line number Diff line number Diff line change
@@ -1,10 +1,7 @@
#import "EXPMatchers+haveCountOf.h"

EXPMatcherImplementationBegin(haveCountOf, (NSUInteger expected)) {
BOOL actualIsCompatible = [actual isKindOfClass:[NSString class]] ||
[actual isKindOfClass:[NSArray class]] ||
[actual isKindOfClass:[NSSet class]] ||
[actual isKindOfClass:[NSDictionary class]];
BOOL actualIsCompatible = [actual isKindOfClass:[NSString class]] || [actual respondsToSelector:@selector(count)];

prerequisite(^BOOL{
return actualIsCompatible;
Expand All @@ -26,13 +23,13 @@
});

failureMessageForTo(^NSString *{
if(!actualIsCompatible) return [NSString stringWithFormat:@"%@ is not an instance of NSString, NSArray, NSSet, or NSDictionary", EXPDescribeObject(actual)];
return [NSString stringWithFormat:@"expected %@ to have a count of %zd but got %zd", EXPDescribeObject(actual), expected, count(actual)];
if(!actualIsCompatible) return [NSString stringWithFormat:@"%@ is not an instance of NSString, NSArray, NSSet, NSOrderedSet, or NSDictionary", EXPDescribeObject(actual)];
return [NSString stringWithFormat:@"expected %@ to have a count of %zi but got %zi", EXPDescribeObject(actual), expected, count(actual)];
});

failureMessageForNotTo(^NSString *{
if(!actualIsCompatible) return [NSString stringWithFormat:@"%@ is not an instance of NSString, NSArray, NSSet, or NSDictionary", EXPDescribeObject(actual)];
return [NSString stringWithFormat:@"expected %@ not to have a count of %zd", EXPDescribeObject(actual), expected];
if(!actualIsCompatible) return [NSString stringWithFormat:@"%@ is not an instance of NSString, NSArray, NSSet, NSOrderedSet, or NSDictionary", EXPDescribeObject(actual)];
return [NSString stringWithFormat:@"expected %@ not to have a count of %zi", EXPDescribeObject(actual), expected];
});
}
EXPMatcherImplementationEnd
24 changes: 24 additions & 0 deletions test/ExpectationTest.m
Original file line number Diff line number Diff line change
Expand Up @@ -174,4 +174,28 @@ - (void)test_expect_struct {
assertFail(test_expect(s).beNil(), @"expecting a struct is not supported");
}

- (void)test_boolean_type_equivalence {
bool noBool = false;
BOOL noBOOL = NO;
int noInt = 0;
id noNSNum = [NSNumber numberWithBool:NO];

_Bool yesBool = true;
BOOL yesBOOL = YES;
int yesInt = 1;
id yesNSNum = [NSNumber numberWithBool:YES];

expect(false).to.equal(NO);
expect(NO).to.equal(noBool);
expect(noBool).to.equal(noBOOL);
expect(noBOOL).to.equal(noInt);
expect(noInt).to.equal(noNSNum);

expect(true).to.equal(YES);
expect(YES).to.equal(yesBool);
expect(yesBool).to.equal(yesBOOL);
expect(yesBOOL).to.equal(yesInt);
expect(yesInt).to.equal(yesNSNum);
}

@end
19 changes: 12 additions & 7 deletions test/matchers/EXPMatchers+haveCountOfTest.m
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
@interface EXPMatchers_haveCountOfTest : SenTestCase {
NSArray *array;
NSSet* set;
NSOrderedSet *orderedSet;
NSDictionary* dictionary;
NSString *string;
NSObject* object;
Expand All @@ -13,7 +14,8 @@ @implementation EXPMatchers_haveCountOfTest

- (void)setUp {
array = [NSArray arrayWithObjects:@"foo", @"bar", @"baz", nil];
set = [NSSet set];
set = [NSSet setWithObjects:@"foo", @"bar", nil];
orderedSet = [NSOrderedSet orderedSetWithObjects:@"foo", @"bar", @"baz", @"qux", nil];
dictionary = [NSDictionary dictionaryWithObjectsAndKeys:@"value", @"key", nil];
string = @"foobar";
object = [NSObject new];
Expand All @@ -22,25 +24,28 @@ - (void)setUp {
- (void)test_haveCountOf {
assertPass(test_expect(array).haveCountOf(3));
assertPass(test_expect(array).haveCount(3));
assertPass(test_expect(set).haveCountOf(0));
assertPass(test_expect(set).beEmpty());
assertPass(test_expect(set).haveCountOf(2));
assertPass(test_expect(orderedSet).haveCountOf(4));
assertPass(test_expect(dictionary).haveCountOf(1));
assertPass(test_expect(string).haveCountOf(6));
assertFail(test_expect(array).haveCountOf(2), @"expected (foo, bar, baz) to have a count of 2 but got 3");
assertFail(test_expect(set).haveCountOf(3), @"expected {(foo, bar)} to have a count of 3 but got 2");
assertFail(test_expect(orderedSet).haveCountOf(3), @"expected {(foo, bar, baz, qux)} to have a count of 3 but got 4");
assertFail(test_expect(string).haveCountOf(3), @"expected foobar to have a count of 3 but got 6");
NSString* errorMessage = [NSString stringWithFormat:@"%@ is not an instance of NSString, NSArray, NSSet, or NSDictionary", object];
NSString* errorMessage = [NSString stringWithFormat:@"%@ is not an instance of NSString, NSArray, NSSet, NSOrderedSet, or NSDictionary", object];
assertFail(test_expect(object).haveCountOf(2), errorMessage);
}

- (void)test_toNot_haveCountOf {
assertPass(test_expect(array).toNot.haveCountOf(5));
assertPass(test_expect(array).toNot.beEmpty());
assertPass(test_expect(set).toNot.haveCount(2));
assertPass(test_expect(set).toNot.haveCountOf(3));
assertPass(test_expect(dictionary).toNot.haveCountOf(6));
assertPass(test_expect(string).toNot.haveCountOf(1));
assertFail(test_expect(array).toNot.haveCountOf(3), @"expected (foo, bar, baz) not to have a count of 3");
assertFail(test_expect(set).notTo.haveCountOf(2), @"expected {(foo, bar)} not to have a count of 2");
assertFail(test_expect(orderedSet).notTo.haveCountOf(4), @"expected {(foo, bar, baz, qux)} not to have a count of 4");
assertFail(test_expect(string).toNot.haveCountOf(6), @"expected foobar not to have a count of 6");
NSString* errorMessage = [NSString stringWithFormat:@"%@ is not an instance of NSString, NSArray, NSSet, or NSDictionary", object];
NSString* errorMessage = [NSString stringWithFormat:@"%@ is not an instance of NSString, NSArray, NSSet, NSOrderedSet, or NSDictionary", object];
assertFail(test_expect(object).toNot.haveCountOf(2), errorMessage);
}

Expand Down

0 comments on commit dc270cf

Please sign in to comment.