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

Commit

Permalink
Merge remote-tracking branch 'petejkim/master'
Browse files Browse the repository at this point in the history
  • Loading branch information
jspahrsummers committed Feb 12, 2013
2 parents 6d86263 + ad9a9fd commit f5b63c9
Show file tree
Hide file tree
Showing 11 changed files with 127 additions and 19 deletions.
10 changes: 3 additions & 7 deletions Expecta.podspec
@@ -1,12 +1,12 @@
Pod::Spec.new do |s|
s.name = 'Expecta'
s.version = '0.2.0'
s.version = '0.2.1'
s.license = 'MIT'
s.summary = 'A matcher framework for Objective-C & Cocoa'
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 => 'http://github.com/petejkim/expecta.git', :tag => 'v0.2.0' }
s.source = { :git => 'https://github.com/petejkim/expecta.git', :tag => 'v0.2.1' }

s.description = %{
Expecta is a matcher framework for Objective-C and Cocoa. The main
Expand All @@ -18,10 +18,6 @@ Pod::Spec.new do |s|

s.source_files = 'src/**/*.{h,m}'

s.clean_paths = "Rakefile", "RDD.md", "products", "test", "*.xcodeproj"

s.frameworks = 'Foundation'

s.xcconfig = { 'OTHER_LDFLAGS' => '-ObjC' }
end

18 changes: 18 additions & 0 deletions Expecta.xcodeproj/project.pbxproj
Expand Up @@ -7,6 +7,12 @@
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 */; };
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 */; };
2546A96316629DF70078E044 /* EXPMatchers+raiseWithReasonTest.m in Sources */ = {isa = PBXBuildFile; fileRef = 2546A96116629DF70078E044 /* EXPMatchers+raiseWithReasonTest.m */; };
4913B4C71411E01A00040ECB /* EXPMatchers+beGreaterThanTest.m in Sources */ = {isa = PBXBuildFile; fileRef = 4913B4C61411E01A00040ECB /* EXPMatchers+beGreaterThanTest.m */; };
4913B4C81411E01A00040ECB /* EXPMatchers+beGreaterThanTest.m in Sources */ = {isa = PBXBuildFile; fileRef = 4913B4C61411E01A00040ECB /* EXPMatchers+beGreaterThanTest.m */; };
4913B4CC1411E18A00040ECB /* EXPMatchers+beGreaterThan.h in Headers */ = {isa = PBXBuildFile; fileRef = 4913B4CA1411E18A00040ECB /* EXPMatchers+beGreaterThan.h */; settings = {ATTRIBUTES = (Public, ); }; };
Expand Down Expand Up @@ -205,6 +211,9 @@
/* End PBXContainerItemProxy section */

/* Begin PBXFileReference section */
2546A95A16629D4F0078E044 /* EXPMatchers+raiseWithReason.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "EXPMatchers+raiseWithReason.h"; sourceTree = "<group>"; };
2546A95B16629D4F0078E044 /* EXPMatchers+raiseWithReason.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "EXPMatchers+raiseWithReason.m"; sourceTree = "<group>"; };
2546A96116629DF70078E044 /* EXPMatchers+raiseWithReasonTest.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "EXPMatchers+raiseWithReasonTest.m"; sourceTree = "<group>"; };
4913B4C61411E01A00040ECB /* EXPMatchers+beGreaterThanTest.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "EXPMatchers+beGreaterThanTest.m"; sourceTree = "<group>"; };
4913B4CA1411E18A00040ECB /* EXPMatchers+beGreaterThan.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "EXPMatchers+beGreaterThan.h"; sourceTree = "<group>"; };
4913B4CB1411E18A00040ECB /* EXPMatchers+beGreaterThan.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "EXPMatchers+beGreaterThan.m"; sourceTree = "<group>"; };
Expand Down Expand Up @@ -454,6 +463,8 @@
63F6F354150A542D009E1BC3 /* EXPMatchers+beCloseTo.m */,
E9D3DF14157A7EB40054978E /* EXPMatchers+raise.h */,
E9D3DF11157A7EA30054978E /* EXPMatchers+raise.m */,
2546A95A16629D4F0078E044 /* EXPMatchers+raiseWithReason.h */,
2546A95B16629D4F0078E044 /* EXPMatchers+raiseWithReason.m */,
);
path = matchers;
sourceTree = "<group>";
Expand Down Expand Up @@ -488,6 +499,7 @@
E9ACDF7513B2DEB70010F4D7 /* EXPMatchers+beFalsyTest.m */,
E9ACDF7B13B2DEB70010F4D7 /* EXPMatchers+equalTest.m */,
E9D3DF0D157A7B7E0054978E /* EXPMatchers+raiseTest.m */,
2546A96116629DF70078E044 /* EXPMatchers+raiseWithReasonTest.m */,
E94296F313B42E160038708B /* EXPMatchers+containTest.m */,
63B349E215135EB100C955DC /* EXPMatchers+haveCountOfTest.m */,
4913B4C61411E01A00040ECB /* EXPMatchers+beGreaterThanTest.m */,
Expand Down Expand Up @@ -575,6 +587,7 @@
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 @@ -613,6 +626,7 @@
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 @@ -798,6 +812,7 @@
A30575661520BDCE00DA19BD /* EXPBlockDefinedMatcher.m in Sources */,
E95368561521BFDB00AA3B81 /* EXPBackwardCompatibility.m in Sources */,
E9D3DF13157A7EA30054978E /* EXPMatchers+raise.m in Sources */,
2546A95F16629D500078E044 /* EXPMatchers+raiseWithReason.m in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
Expand Down Expand Up @@ -832,6 +847,7 @@
A30575AB1520F61500DA19BD /* DynamicPredicateMatcherTest.m in Sources */,
E9D3DF0F157A7B7E0054978E /* EXPMatchers+raiseTest.m in Sources */,
E9D3DF1C157A8AC30054978E /* EXPMatchers+beCloseToTest.m in Sources */,
2546A96316629DF70078E044 /* EXPMatchers+raiseWithReasonTest.m in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
Expand Down Expand Up @@ -866,6 +882,7 @@
A30575651520BDCE00DA19BD /* EXPBlockDefinedMatcher.m in Sources */,
E95368551521BFDB00AA3B81 /* EXPBackwardCompatibility.m in Sources */,
E9D3DF12157A7EA30054978E /* EXPMatchers+raise.m in Sources */,
2546A95E16629D500078E044 /* EXPMatchers+raiseWithReason.m in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
Expand Down Expand Up @@ -900,6 +917,7 @@
A30575A91520F5FE00DA19BD /* DynamicPredicateMatcherTest.m in Sources */,
E9D3DF0E157A7B7E0054978E /* EXPMatchers+raiseTest.m in Sources */,
E9D3DF1B157A8AC30054978E /* EXPMatchers+beCloseToTest.m in Sources */,
2546A96216629DF70078E044 /* EXPMatchers+raiseWithReasonTest.m in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
Expand Down
6 changes: 3 additions & 3 deletions README.md
@@ -1,4 +1,4 @@
# Expecta 0.2.0
# Expecta

A Matcher Framework for Objective-C/Cocoa

Expand Down Expand Up @@ -35,8 +35,8 @@ expect(baz).to.equal(3.14159);
Use [CocoaPods](https://github.com/CocoaPods/CocoaPods)

```ruby
dependency 'Expecta', '~> 0.2.0'
# dependency 'Specta', '~> 0.1.5' # specta bdd framework
dependency 'Expecta', '~> 0.2.1'
# dependency 'Specta', '~> 0.1.7' # specta bdd framework
```

or
Expand Down
2 changes: 1 addition & 1 deletion src/EXPFloatTuple.m
Expand Up @@ -36,7 +36,7 @@ - (NSString *)description {
} else if (self.size == 4) {
return [NSString stringWithFormat:@"Float tuple: {%f, %f, %f, %f}", self.values[0], self.values[1], self.values[2], self.values[3]];
}
return [NSString stringWithFormat:@"Float tuple of unexpected size %li, sadly", self.size];
return [NSString stringWithFormat:@"Float tuple of unexpected size %zd, sadly", self.size];
}

@end
9 changes: 6 additions & 3 deletions src/ExpectaSupport.m
Expand Up @@ -53,14 +53,17 @@ id _EXPObjectify(char *type, ...) {
} else if(strcmp(type, @encode(unsigned short)) == 0) {
unsigned short actual = (unsigned short)va_arg(v, unsigned int);
obj = [NSNumber numberWithUnsignedShort:actual];
} else if(strstr(type, @encode(EXPBasicBlock)) != NULL) {
// @encode(EXPBasicBlock) returns @? as of clang 4.1.
// This condition must occur before the test for id/class type,
// otherwise blocks will be treated as vanilla objects.
id actual = va_arg(v, EXPBasicBlock);
obj = [[actual copy] autorelease];
} else if((strstr(type, @encode(id)) != NULL) || (strstr(type, @encode(Class)) != 0)) {
id actual = va_arg(v, id);
obj = actual;
} else if(strcmp(type, @encode(__typeof__(nil))) == 0) {
obj = nil;
} else if(strstr(type, @encode(EXPBasicBlock)) != NULL) {
id actual = va_arg(v, EXPBasicBlock);
obj = [[actual copy] autorelease];
} else if(strstr(type, "ff}{") != NULL) { //TODO: of course this only works for a 2x2 e.g. CGRect
obj = [[[EXPFloatTuple alloc] initWithFloatValues:(float *)va_arg(v, float[4]) size:4] autorelease];
} else if(strstr(type, "=ff}") != NULL) {
Expand Down
10 changes: 5 additions & 5 deletions src/matchers/EXPMatchers+haveCountOf.m
Expand Up @@ -3,8 +3,8 @@
EXPMatcherImplementationBegin(haveCountOf, (NSUInteger expected)) {
BOOL actualIsCompatible = [actual isKindOfClass:[NSString class]] ||
[actual isKindOfClass:[NSArray class]] ||
[actual isKindOfClass:[NSSet class]] ||
[actual isKindOfClass:[NSDictionary class]];
[actual isKindOfClass:[NSSet class]] ||
[actual isKindOfClass:[NSDictionary class]];

prerequisite(^BOOL{
return actualIsCompatible;
Expand All @@ -13,7 +13,7 @@
NSUInteger (^count)(id) = ^(id actual) {
if([actual isKindOfClass:[NSString class]]) {
return [actual length];
} else {
} else {
return [actual count];
}
};
Expand All @@ -27,12 +27,12 @@

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 %zi but got %zi", EXPDescribeObject(actual), expected, count(actual)];
return [NSString stringWithFormat:@"expected %@ to have a count of %zd but got %zd", 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 %zi", EXPDescribeObject(actual), expected];
return [NSString stringWithFormat:@"expected %@ not to have a count of %zd", EXPDescribeObject(actual), expected];
});
}
EXPMatcherImplementationEnd
3 changes: 3 additions & 0 deletions src/matchers/EXPMatchers+raiseWithReason.h
@@ -0,0 +1,3 @@
#import "Expecta.h"

EXPMatcherInterface(raiseWithReason, (NSString *expectedExceptionName, NSString *expectedReason));
35 changes: 35 additions & 0 deletions src/matchers/EXPMatchers+raiseWithReason.m
@@ -0,0 +1,35 @@
#import "EXPMatchers+raiseWithReason.h"
#import "EXPDefines.h"

EXPMatcherImplementationBegin(raiseWithReason, (NSString *expectedExceptionName, NSString *expectedReason)) {
__block NSException *exceptionCaught = nil;

match(^BOOL{
BOOL expectedExceptionCaught = NO;
@try {
((EXPBasicBlock)actual)();
} @catch(NSException *e) {
exceptionCaught = e;
expectedExceptionCaught = (((expectedExceptionName == nil) || [[exceptionCaught name] isEqualToString:expectedExceptionName]) &&
((expectedReason == nil) || ([[exceptionCaught reason] isEqualToString:expectedReason])));
}
return expectedExceptionCaught;
});

failureMessageForTo(^NSString *{
return [NSString stringWithFormat:@"expected: %@ (%@), got: %@ (%@)",
expectedExceptionName ?: @"any exception",
expectedReason ?: @"any reason",
exceptionCaught ? [exceptionCaught name] : @"no exception",
exceptionCaught ? [exceptionCaught reason] : @""];
});

failureMessageForNotTo(^NSString *{
return [NSString stringWithFormat:@"expected: %@ (%@), got: %@ (%@)",
expectedExceptionName ? [NSString stringWithFormat:@"not %@", expectedExceptionName] : @"no exception",
expectedReason ? [NSString stringWithFormat:@"not '%@'", expectedReason] : @"no reason",
exceptionCaught ? [exceptionCaught name] : @"no exception",
exceptionCaught ? [exceptionCaught reason] : @"no reason"];
});
}
EXPMatcherImplementationEnd
1 change: 1 addition & 0 deletions src/matchers/EXPMatchers.h
Expand Up @@ -15,3 +15,4 @@
#import "EXPMatchers+beInTheRangeOf.h"
#import "EXPMatchers+beCloseTo.h"
#import "EXPMatchers+raise.h"
#import "EXPMatchers+raiseWithReason.h"
8 changes: 8 additions & 0 deletions test/MiscTest.m
Expand Up @@ -20,4 +20,12 @@ - (void)test_StrippingOfLineBreaksInObjectDescription {
expect(EXPDescribeObject(dict)).equal(@"{foo = bar;}");
}

- (void)test_EXPObjectifyCopiesObjectsWithBlockType
{
id original = [[NSMutableArray alloc] init];
id copy = _EXPObjectify(@encode(EXPBasicBlock), original);

expect(original == copy).to.beFalsy();
}

@end
44 changes: 44 additions & 0 deletions test/matchers/EXPMatchers+raiseWithReasonTest.m
@@ -0,0 +1,44 @@
#import "TestHelper.h"

@interface EXPMatchers_raiseWithReasonTest : SenTestCase
@end

@implementation EXPMatchers_raiseWithReasonTest

- (void)test_raiseWithReason {
assertPass(test_expect(^{
[NSException raise:@"TestException" format:@"This is the reason"];
}).to.raiseWithReason(@"TestException", @"This is the reason"));

assertFail(test_expect(^{
// not raising...
}).to.raiseWithReason(@"TestException", @"This is the reason"), @"expected: TestException (This is the reason), got: no exception ()");

assertFail(test_expect(^{
NSException *exception = [NSException exceptionWithName:@"AnotherException" reason:@"This is the reason" userInfo:nil];
[exception raise];
}).to.raiseWithReason(@"TestException", @"This is the reason"), @"expected: TestException (This is the reason), got: AnotherException (This is the reason)");
}

- (void)test_toNot_raiseWithReason {
assertFail(test_expect(^{
[NSException raise:@"TestException" format:@"This is the reason"];
}).notTo.raiseWithReason(@"TestException", @"This is the reason"), @"expected: not TestException (not 'This is the reason'), got: TestException (This is the reason)");

assertPass(test_expect(^{
// Different reason text than expected
[NSException raise:@"TestException" format:@"A different reason"];
}).notTo.raiseWithReason(@"TestException", @"This is the reason"));

assertPass(test_expect(^{
// not raising...
}).notTo.raiseWithReason(@"TestException", @"This is the reason"));

assertPass(test_expect(^{
// Different exception class
NSException *exception = [NSException exceptionWithName:@"AnotherException" reason:nil userInfo:nil];
[exception raise];
}).notTo.raiseWithReason(@"TestException", @"This is the reason"));
}

@end

0 comments on commit f5b63c9

Please sign in to comment.