Skip to content

[XCTestExpectation] Adding expectationForPredicate constructor #103

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
May 4, 2016

Conversation

minoltax700
Copy link
Contributor

@minoltax700 minoltax700 commented May 2, 2016

What's in this pull request?

This pull request adds the XCTestCase convenience constructor for XCTestExpectation expectation(forPredicate:evaluatedWithObject:handler:).

I added XCPredicateExpectation, an internal subclass of XCTestExpectation, to keep the evaluation logic separated (and to match the obj-c implementation). The re-evaluation interval has been shorted to 0.01 whereas the obj-c interval is about once per second.

This also includes a separate file for the typealias XCPredicateExpectationHandler.

There are tests for the expectation and the handler. Let me know if you think there should be more tests, I'd be happy to add other ideas.

https://bugs.swift.org/browse/SR-1110

Why merge this pull request?

This will provide a full Swift implementation of expectationForPredicate:evaluatedWithObject:handler: that allows asynchronous testing for NSPredicate.

// CHECK: Test Suite 'PredicateExpectationsTestCase' started at \d+:\d+:\d+\.\d+
class PredicateExpectationsTestCase: XCTestCase {
// CHECK: Test Case 'PredicateExpectationsTestCase.test_immediatelyTruePredicateAndObject_passes' started at \d+:\d+:\d+\.\d+
// CHECK: Test Case 'PredicateExpectationsTestCase.test_immediatelyTruePredicateAndObject_passes' passed \(\d+\.\d+ seconds\).
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

With #94 merged you may now indent the // CHECK:, like so:

func myFunc() {
    // CHECK: foo
    print("foo")
    if (bar) {
        // CHECK: baz
        print("baz")
    }
}

I think indenting is more readable, so I'd encourage you to do that! (I had been meaning to start sending out pull requests to indent the checks in the tests, but forgot 😇 )

@modocache
Copy link
Contributor

This is really excellent work, @yoonapps, thank you!!

@mike-ferris-apple Could you ask @swift-ci to please test?

@minoltax700
Copy link
Contributor Author

@modocache Addressed reviews! I lowered the interval to 0.01 and updated the tests to wait for only 0.1.

@ddunbar
Copy link
Contributor

ddunbar commented May 3, 2016

@swift-ci please test

/// first successful evaluation will fulfill the expectation. If provided,
/// the handler can override that behavior which leaves the caller
/// responsible for fulfilling the expectation.
public func expectation(forPredicate predicate: NSPredicate, evaluatedWithObject object: AnyObject, file: StaticString = #file, line: UInt = #line, handler: XCPredicateExpectationHandler? = nil) -> XCPredicateExpectation {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think the precise signature of this method needs to be adjusted. I'm seeing the following imported signature in Xcode using the latest Swift toolchain:

public func expectation(for predicate: NSPredicate, evaluatedWith object: AnyObject, handler: XCPredicateExpectationHandler? = nil) -> XCTestExpectation

Does this look right? @mike-ferris-apple @modocache

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Agreed. This was generated with the Swift 3 importer from a month ago, but it matches @briancroom's signature.

@briancroom
Copy link
Contributor

Excited to see this come in @yoonapps, thanks! I just left a couple questions.

@minoltax700
Copy link
Contributor Author

minoltax700 commented May 3, 2016

I'm learning so much every PR! It's awesome.
@briancroom Thank you for fixing the strong reference issue in the expectationForNotification! I applied a similar fix here. I use weak self for networking a whole bunch at work. Such a "duh" moment. 😆
One question, I was going to fix the signature for init of XCPredicateExpectation as well but it looked like inits don't follow the same rules. Is that right?

@minoltax700 minoltax700 force-pushed the master branch 3 times, most recently from c586eef to f737155 Compare May 3, 2016 16:21
timer.invalidate()
}
}
})
Copy link
Contributor Author

@minoltax700 minoltax700 May 3, 2016

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I've tried CTRL + I here but this is where the indentation goes. Does this look funky or is it just me?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, it does look strange. Personally, I would remove four spaces, in order to align it with the open brace on the self.timer = NSTimer.scheduledTimer(self.evaluationInterval, repeats: true, fire: { line. It's up to you, though! :)

@modocache
Copy link
Contributor

One question, I was going to fix the signature for init of XCPredicateExpectation as well but it looked like inits don't follow the same rules.

Good observation! Apple XCTest doesn't provide a public initializer for XCTestExpectation, nor does it provide a public definition of any of its private subclasses (such as _XCPredicateExpectation). So we don't need to worry about providing an identical signature: no users of Apple XCTest should ever initialize an XCTestExpectation directly.

@minoltax700
Copy link
Contributor Author

minoltax700 commented May 3, 2016

Gotcha! Is there anything else that needs to be addressed?

@modocache
Copy link
Contributor

@briancroom does the timer invalidation look good?

@mike-ferris-apple Could you ask @swift-ci to please test?

@ddunbar
Copy link
Contributor

ddunbar commented May 4, 2016

@swift-ci please test

@briancroom
Copy link
Contributor

Looks great! Nice work @yoonapps

import SwiftFoundation
#endif

public class XCPredicateExpectation: XCTestExpectation {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actually, just one more thing - can we make this subclass have internal visibility, and return the base class type from the factory method on XCTestCase?

- Added class XCPredicateExpectation
- Added typealias for XCPredicateExpectationHandler
- Added tests for the expectation and handler
@minoltax700
Copy link
Contributor Author

@briancroom Ah!! I had it internal initially but changed to public because of the factory method return type. I didn't realize that I could just return the base type! 😱💥 Mind blown.

@modocache
Copy link
Contributor

Excellent, thanks @yoonapps!! That's two tasks under your belt! 💯

@modocache modocache merged commit df38089 into swiftlang:master May 4, 2016
@minoltax700
Copy link
Contributor Author

Not a problem. The experience I'm getting from these tasks are invaluable. Thanks for sending this task my way, @modocache! I'm always ready for more so let me know if you have any suggestions.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants