Skip to content

Commit

Permalink
Synced upstream changes
Browse files Browse the repository at this point in the history
  • Loading branch information
abbeycode committed May 6, 2016
2 parents 9cf0432 + 42e9bfd commit d92b92b
Show file tree
Hide file tree
Showing 36 changed files with 634 additions and 294 deletions.
1 change: 1 addition & 0 deletions .ruby-version
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
system
4 changes: 4 additions & 0 deletions .travis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,9 @@ osx_image: xcode7.3
language: generic
matrix:
include:
- os: osx
sudo: required
env: TYPE=podspec
- os: osx
env: NIMBLE_RUNTIME_IOS_SDK_VERSION=9.0 TYPE=ios
- os: osx
Expand All @@ -14,5 +17,6 @@ matrix:
env: TYPE=swiftpm
install:
- if [[ "$TYPE" == "swiftpm" ]]; then eval "$(curl -sL https://gist.githubusercontent.com/kylef/5c0475ff02b7c7671d2a/raw/02090c7ede5a637b76e6df1710e83cd0bbe7dcdf/swiftenv-install.sh)"; fi
- if [[ "$TYPE" == "podspec" ]]; then sudo gem install bundler; bundle install; fi
script:
- ./test $TYPE
5 changes: 2 additions & 3 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -112,9 +112,8 @@ The process is relatively straight forward, but here's is a useful checklist for

- Look at changes from the previously tagged release and write release notes: `git log v0.4.0...HEAD`
- Run the release script: `./script/release A.B.C release-notes-file`
- Go to [github releases](https://github.com/Quick/Nimble/releases) and mark the tagged commit as a release.
- Use the same release notes you created for the tag, but tweak up formatting for github.
- Attach the carthage release `Nimble.framework.zip` to the release.
- The script will prompt you to create a new [GitHub release](https://github.com/Quick/Nimble/releases).
- Use the same release notes you created for the tag, but tweak up formatting for GitHub.
- Update [Quick](https://github.com/Quick/Quick)
- Update Quick's submodule reference to the newly released Nimble version
- Update Nimble version in `README.md` and Documentation in [Quick](https://github.com/Quick/Quick) if it's not a patch version update.
Expand Down
4 changes: 4 additions & 0 deletions Gemfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
# A sample Gemfile
source "https://rubygems.org"

gem 'cocoapods'
63 changes: 63 additions & 0 deletions Gemfile.lock
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
GEM
remote: https://rubygems.org/
specs:
activesupport (4.2.6)
i18n (~> 0.7)
json (~> 1.7, >= 1.7.7)
minitest (~> 5.1)
thread_safe (~> 0.3, >= 0.3.4)
tzinfo (~> 1.1)
claide (0.9.1)
cocoapods (0.39.0)
activesupport (>= 4.0.2)
claide (~> 0.9.1)
cocoapods-core (= 0.39.0)
cocoapods-downloader (~> 0.9.3)
cocoapods-plugins (~> 0.4.2)
cocoapods-search (~> 0.1.0)
cocoapods-stats (~> 0.6.2)
cocoapods-trunk (~> 0.6.4)
cocoapods-try (~> 0.5.1)
colored (~> 1.2)
escape (~> 0.0.4)
molinillo (~> 0.4.0)
nap (~> 1.0)
xcodeproj (~> 0.28.2)
cocoapods-core (0.39.0)
activesupport (>= 4.0.2)
fuzzy_match (~> 2.0.4)
nap (~> 1.0)
cocoapods-downloader (0.9.3)
cocoapods-plugins (0.4.2)
nap
cocoapods-search (0.1.0)
cocoapods-stats (0.6.2)
cocoapods-trunk (0.6.4)
nap (>= 0.8, < 2.0)
netrc (= 0.7.8)
cocoapods-try (0.5.1)
colored (1.2)
escape (0.0.4)
fuzzy_match (2.0.4)
i18n (0.7.0)
json (1.8.3)
minitest (5.8.4)
molinillo (0.4.4)
nap (1.1.0)
netrc (0.7.8)
thread_safe (0.3.5)
tzinfo (1.2.2)
thread_safe (~> 0.1)
xcodeproj (0.28.2)
activesupport (>= 3)
claide (~> 0.9.1)
colored (~> 1.2)

PLATFORMS
ruby

DEPENDENCIES
cocoapods

BUNDLED WITH
1.11.2
4 changes: 3 additions & 1 deletion Nimble.podspec
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
Pod::Spec.new do |s|
s.name = "Nimble"
s.version = "3.2.0"
s.version = "4.0.1"
s.summary = "A Matcher Framework for Swift and Objective-C"
s.description = <<-DESC
Use Nimble to express the expected outcomes of Swift or Objective-C expressions. Inspired by Cedar.
Expand All @@ -14,6 +14,8 @@ Pod::Spec.new do |s|
s.source = { :git => "https://github.com/Quick/Nimble.git", :tag => "v#{s.version}" }

s.source_files = "Sources/Nimble/**/*.{swift,h,m}"
s.private_header_files = "Sources/Nimble/Adapters/ObjectiveC/CurrentTestCaseTracker.h"
s.exclude_files = "Sources/Nimble/Adapters/NonObjectiveC/*.swift"
s.weak_framework = "XCTest"
s.requires_arc = true
s.pod_target_xcconfig = { 'ENABLE_BITCODE' => 'NO', 'OTHER_LDFLAGS' => '-weak-lswiftXCTest', 'FRAMEWORK_SEARCH_PATHS' => '$(inherited) "$(PLATFORM_DIR)/Developer/Library/Frameworks"' }
Expand Down
262 changes: 142 additions & 120 deletions Nimble.xcodeproj/project.pbxproj

Large diffs are not rendered by default.

25 changes: 21 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -394,10 +394,10 @@ the default timeout and poll interval values. This can be done as follows:
// Swift
// Increase the global timeout to 5 seconds:
Nimble.Defaults.AsyncTimeout = 5
Nimble.AsyncDefaults.Timeout = 5
// Slow the polling interval to 0.1 seconds:
Nimble.Defaults.AsyncPollInterval = 0.1
Nimble.AsyncDefaults.PollInterval = 0.1
```

## Objective-C Support
Expand Down Expand Up @@ -717,6 +717,23 @@ expect{ try somethingThatThrows() }.to(throwError(NSCocoaError.PropertyListReadC
expect{ try somethingThatThrows() }.to(throwError(errorType: MyError.self))
```

If you are working directly with `ErrorType` values, as is sometimes the case when using `Result` or `Promise` types, you can use the `matchError` matcher to check if the error is the same error is is supposed to be, without requiring explicit casting.

```swift
// Swift

let actual: ErrorType =

// Passes if actual contains any error value from the MyErrorEnum type:
expect(actual).to(matchError(MyErrorEnum))

// Passes if actual contains the Timeout value from the MyErrorEnum type:
expect(actual).to(matchError(MyErrorEnum.Timeout))

// Passes if actual contains an NSError equal to the given one:
expect(actual).to(matchError(NSError(domain: "err", code: 123, userInfo: nil)))
```

Note: This feature is only available in Swift.

## Exceptions
Expand Down Expand Up @@ -983,7 +1000,7 @@ in an Xcode project you distribute to others.
distribute it yourself via GitHub.

For examples of how to write your own matchers, just check out the
[`Matchers` directory](https://github.com/Quick/Nimble/tree/master/Nimble/Matchers)
[`Matchers` directory](https://github.com/Quick/Nimble/tree/master/Sources/Nimble/Matchers)
to see how Nimble's built-in set of matchers are implemented. You can
also check out the tips below.

Expand Down Expand Up @@ -1190,7 +1207,7 @@ source 'https://github.com/CocoaPods/Specs.git'

target 'YOUR_APP_NAME_HERE_Tests', :exclusive => true do
use_frameworks!
pod 'Nimble', '~> 3.1.0'
pod 'Nimble', '~> 4.0.0'
end
```

Expand Down
File renamed without changes.
Original file line number Diff line number Diff line change
Expand Up @@ -7,12 +7,3 @@ + (CurrentTestCaseTracker *)sharedInstance;
@end

@interface CurrentTestCaseTracker (Register) @end

@implementation CurrentTestCaseTracker (Register)

+ (void)load {
CurrentTestCaseTracker *tracker = [CurrentTestCaseTracker sharedInstance];
[[XCTestObservationCenter sharedTestObservationCenter] addTestObserver:tracker];
}

@end
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
#import "CurrentTestCaseTracker.h"
#import <XCTest/XCTest.h>
#import <objc/runtime.h>

#pragma mark - Method Swizzling

/// Swaps the implementations between two instance methods.
///
/// @param class The class containing `originalSelector`.
/// @param originalSelector Original method to replace.
/// @param replacementSelector Replacement method.
void swizzleSelectors(Class class, SEL originalSelector, SEL replacementSelector) {
Method originalMethod = class_getInstanceMethod(class, originalSelector);
Method replacementMethod = class_getInstanceMethod(class, replacementSelector);

BOOL didAddMethod =
class_addMethod(class,
originalSelector,
method_getImplementation(replacementMethod),
method_getTypeEncoding(replacementMethod));

if (didAddMethod) {
class_replaceMethod(class,
replacementSelector,
method_getImplementation(originalMethod),
method_getTypeEncoding(originalMethod));
} else {
method_exchangeImplementations(originalMethod, replacementMethod);
}
}

#pragma mark - Private

@interface XCTestObservationCenter (Private)
- (void)_addLegacyTestObserver:(id)observer;
@end

@implementation XCTestObservationCenter (Register)

/// Uses objc method swizzling to register `CurrentTestCaseTracker` as a test observer. This is necessary
/// because Xcode 7.3 introduced timing issues where if a custom `XCTestObservation` is registered too early
/// it suppresses all console output (generated by `XCTestLog`), breaking any tools that depend on this output.
/// This approach waits to register our custom test observer until XCTest adds its first "legacy" observer,
/// falling back to registering after the first normal observer if this private method ever changes.
+ (void)load {
if (class_getInstanceMethod([self class], @selector(_addLegacyTestObserver:))) {
// Swizzle -_addLegacyTestObserver:
swizzleSelectors([self class], @selector(_addLegacyTestObserver:), @selector(NMB_original__addLegacyTestObserver:));
} else {
// Swizzle -addTestObserver:, only if -_addLegacyTestObserver: is not implemented
swizzleSelectors([self class], @selector(addTestObserver:), @selector(NMB_original_addTestObserver:));
}
}

#pragma mark - Replacement Methods

/// Registers `CurrentTestCaseTracker` as a test observer after `XCTestLog` has been added.
- (void)NMB_original__addLegacyTestObserver:(id)observer {
[self NMB_original__addLegacyTestObserver:observer];

static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
[self addTestObserver:[CurrentTestCaseTracker sharedInstance]];
});
}

/// Registers `CurrentTestCaseTracker` as a test observer after `XCTestLog` has been added.
/// This method is only used if `-_addLegacyTestObserver:` is not impelemented. (added in Xcode 7.3)
- (void)NMB_original_addTestObserver:(id<XCTestObservation>)observer {
[self NMB_original_addTestObserver:observer];

static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
[self NMB_original_addTestObserver:[CurrentTestCaseTracker sharedInstance]];
});
}

@end
2 changes: 1 addition & 1 deletion Sources/Nimble/Matchers/BeEmpty.swift
Original file line number Diff line number Diff line change
Expand Up @@ -82,7 +82,7 @@ extension NMBObjCMatcher {
let expr = Expression(expression: ({ value as String }), location: location)
return try! beEmpty().matches(expr, failureMessage: failureMessage)
} else if let actualValue = actualValue {
failureMessage.postfixMessage = "be empty (only works for NSArrays, NSSets, NSDictionaries, NSHashTables, and NSStrings)"
failureMessage.postfixMessage = "be empty (only works for NSArrays, NSSets, NSIndexSets, NSDictionaries, NSHashTables, and NSStrings)"
failureMessage.actualValue = "\(classAsString(actualValue.dynamicType)) type"
}
return false
Expand Down
4 changes: 2 additions & 2 deletions Sources/Nimble/Matchers/HaveCount.swift
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import Foundation
public func haveCount<T: CollectionType>(expectedValue: T.Index.Distance) -> NonNilMatcherFunc<T> {
return NonNilMatcherFunc { actualExpression, failureMessage in
if let actualValue = try actualExpression.evaluate() {
failureMessage.postfixMessage = "have \(actualValue) with count \(expectedValue)"
failureMessage.postfixMessage = "have \(stringify(actualValue)) with count \(stringify(expectedValue))"
let result = expectedValue == actualValue.count
failureMessage.actualValue = "\(actualValue.count)"
return result
Expand All @@ -20,7 +20,7 @@ public func haveCount<T: CollectionType>(expectedValue: T.Index.Distance) -> Non
public func haveCount(expectedValue: Int) -> MatcherFunc<NMBCollection> {
return MatcherFunc { actualExpression, failureMessage in
if let actualValue = try actualExpression.evaluate() {
failureMessage.postfixMessage = "have \(actualValue) with count \(expectedValue)"
failureMessage.postfixMessage = "have \(stringify(actualValue)) with count \(stringify(expectedValue))"
let result = expectedValue == actualValue.count
failureMessage.actualValue = "\(actualValue.count)"
return result
Expand Down
26 changes: 26 additions & 0 deletions Sources/Nimble/Matchers/MatchError.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
import Foundation

/// A Nimble matcher that succeeds when the actual expression evaluates to an
/// error from the specified case.
///
/// Errors are tried to be compared by their implementation of Equatable,
/// otherwise they fallback to comparision by _domain and _code.
public func matchError<T: ErrorType>(error: T) -> NonNilMatcherFunc<ErrorType> {
return NonNilMatcherFunc { actualExpression, failureMessage in
let actualError: ErrorType? = try actualExpression.evaluate()

setFailureMessageForError(failureMessage, postfixMessageVerb: "match", actualError: actualError, error: error)
return errorMatchesNonNilFieldsOrClosure(actualError, error: error)
}
}

/// A Nimble matcher that succeeds when the actual expression evaluates to an
/// error of the specified type
public func matchError<T: ErrorType>(errorType: T.Type) -> NonNilMatcherFunc<ErrorType> {
return NonNilMatcherFunc { actualExpression, failureMessage in
let actualError: ErrorType? = try actualExpression.evaluate()

setFailureMessageForError(failureMessage, postfixMessageVerb: "match", actualError: actualError, errorType: errorType)
return errorMatchesNonNilFieldsOrClosure(actualError, errorType: errorType)
}
}
File renamed without changes.
1 change: 1 addition & 0 deletions Sources/Nimble/Matchers/MatcherProtocols.swift
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@ public protocol NMBCollection {
#endif

extension NSSet : NMBCollection {}
extension NSIndexSet : NMBCollection {}
extension NSDictionary : NMBCollection {}

#if _runtime(_ObjC)
Expand Down
Loading

0 comments on commit d92b92b

Please sign in to comment.