Skip to content
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

[SR-1110] Add convenience XCTestExpectation constructors for NSPredicate #396

Closed
modocache mannequin opened this issue Mar 30, 2016 · 10 comments
Closed

[SR-1110] Add convenience XCTestExpectation constructors for NSPredicate #396

modocache mannequin opened this issue Mar 30, 2016 · 10 comments

Comments

@modocache
Copy link
Mannequin

modocache mannequin commented Mar 30, 2016

Previous ID SR-1110
Radar None
Original Reporter @modocache
Type New Feature
Status Closed
Resolution Done

Attachment: Download

Additional Detail from JIRA
Votes 0
Component/s XCTest
Labels New Feature, StarterBug
Assignee apps.yoon (JIRA)
Priority Medium

md5: 80de972c44d4ad944e39eb5cd68136b2

Issue Description:

Apple XCTest offers several convenient methods for constructing XCTestExpectations:

@interface XCTestCase : XCTest
// ...
- (XCTestExpectation *)keyValueObservingExpectationForObject:(id)objectToObserve keyPath:(NSString *)keyPath expectedValue:(nullable id)expectedValue;
- (XCTestExpectation *)keyValueObservingExpectationForObject:(id)objectToObserve keyPath:(NSString *)keyPath handler:(nullable XCKeyValueObservingExpectationHandler)handler;
- (XCTestExpectation *)expectationForNotification:(NSString *)notificationName object:(nullable id)objectToObserve handler:(nullable XCNotificationExpectationHandler)handler;
- (XCTestExpectation *)expectationForPredicate:(NSPredicate *)predicate evaluatedWithObject:(id)object handler:(nullable XCPredicateExpectationHandler)handler;
// ...
@end

Key-value observing doesn't exist in native Swift, but NSNotification and NSPredicate do (thanks to swift-corelibs-foundation). swift-corelibs-xctest already defines a constructor for NSNotification: https://github.com/yoonapps/swift-corelibs-xctest/blob/c2a9258c7c17e32bf9082709ef111e59aba86a95/Sources/XCTest/XCTestCase.swift#L324. This was added in #85

Add the constructor for NSPredicate: -[XCTestCase expectationForPredicate:evaluatedWithObject:handler:].

Also, note that you'll need to add the following closure typealias as well: typedef BOOL (^XCPredicateExpectationHandler)();.

https://bugs.swift.org/browse/SR-907 is a great reference on how to approach this task.

@modocache
Copy link
Mannequin Author

modocache mannequin commented Mar 30, 2016

This task is blocked until swift-corelibs-foundation implements NSPredicate. See: apple/swift-corelibs-foundation#127

@modocache
Copy link
Mannequin Author

modocache mannequin commented Apr 14, 2016

apple/swift-corelibs-foundation#127 was merged! apps.yoon (JIRA User), do you still want to take this on?

@swift-ci
Copy link

Comment by Kyle Yoon (JIRA)

@modocache Sure thing! Assigning to myself.

@swift-ci
Copy link

Comment by Kyle Yoon (JIRA)

@modocache Could I get you thoughts on my implementation:

Since `expectation(forPredicate...)` needs to re-evaluate the predicate periodically, and `waitForExpectations(...)` runs a loop to check if the expectation `isFulfilled`, I make a subclass of `XCTestExpectation` that:

  • holds the predicate and the object with which to evaluate it

  • overrides `isFulfilled` to evaluate the predicate.

Would you be against adding this subclass?

@modocache
Copy link
Mannequin Author

modocache mannequin commented Apr 17, 2016

I think a subclass sounds fine--in fact, I think Apple's XCTest uses a subclass. I don't think it overrides isFulfilled, though. Instead, it probably re-evaluates the predicate periodically, probably using a timer or something.

But that aside, I'd be fine with pretty much any working implementation, even one that overrides isFulfilled. Because XCTest has such a robust suite of tests, I think anything that works is a great step forward--we can find room to refactor the implementation at a later time.

By the way, have you seen this FIXME? Perhaps using a runloop source that could be signaled would make it easier to implement this? If not no worries, just a heads up.

@swift-ci
Copy link

Comment by Kyle Yoon (JIRA)

@modocache
Is there a way to pass the memory address of an object declared in a functional test to // CHECK:?
I've tried using string interpolation and unsafeAddress(of🙂 but haven't had any luck.

@swift-ci
Copy link

Comment by Kyle Yoon (JIRA)

I've tried using the regex ^0x[0-9A-Fa-f]{1,16}$ but I'm getting the error "Actual line did not match the regular expression".

Full line:

// CHECK: .*/Tests/Functional/Asynchronous/Predicates/Expectations/main.swift:34: error: PredicateExpectationsTestCase.test_immediatelyFalsePredicateAndObject_fails : Asynchronous wait failed - Exceeded timeout of 0.1 seconds, with unfulfilled expectations: Expect `<NSPredicate: ^0x[0-9A-Fa-f]\{1,16\}$>` for object <NSObject: ^0x[0-9A-Fa-f]\{1,16\}$>

@modocache
Copy link
Mannequin Author

modocache mannequin commented Apr 29, 2016

apps.yoon (JIRA User): \^ matches the beginning of a line, $ matches the end of a line. Your regular expression would match if the entire line was just a memory address, but not if the line contained a memory address. Have you tried just 0x[0-9A-Fa-f]{1,16}, without the \^$?

@swift-ci
Copy link

swift-ci commented May 2, 2016

Comment by Kyle Yoon (JIRA)

@modocache I've been getting linker errors and have not been able to get a build going. Do you mind taking a look at the ? I can't figure out what I screwed up :/

Ignore that 😃 sorry!

@swift-ci
Copy link

swift-ci commented May 2, 2016

Comment by Kyle Yoon (JIRA)

And yes, your regex fix worked. Thank you!

@swift-ci swift-ci transferred this issue from apple/swift-issues Apr 25, 2022
@shahmishal shahmishal transferred this issue from apple/swift May 9, 2022
This issue was closed.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

1 participant