-
-
Notifications
You must be signed in to change notification settings - Fork 911
Upgrading a large codebase to Quick 6 is really problematic and toEventually
is broken in Obj-C
#1189
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
Comments
My apologies for breaking toEventually in objective-c. The lack of objective-c support for toEventually is definitely problematic. I'll find time to address this (it still might be a while), which will likely involve fixing the poor upgrade experience. This will likely end up looking like 2 separate XCTestCase subclasses for people to choose from when creating a test: Once this is in (plus some time to marinate and be tested out), I'll release it as Quick 7. |
Amazing, thanks so much! I was thinking about a similar solution, providing two subclasses so consumers can decide which one to choose |
That's great to hear, thanks a lot! |
@younata when the Version 7.0.0 is planned to get the release tag? |
I don't 8000 have a concrete date planned. I'm currently recovering from COVID, so I'm focusing more on that than on Quick. The main task left to do before releases 7.0.0 is updating our documentation. Other than that, I'd really like to provide some way to run all tests in an |
I hope you recover fast, and think of great solutions while resting! ❤️🩹 |
Thanks! Quick 7 is now released! I'm still recovering, but I also was incredibly bored. There's still not a solution to have all closures in an I'm going to close this issue as I consider this to be fixed. Upgrading from Quick 5 to Quick 7, while not a drop-in, is much simpler than upgrading to Quick 6. For the most part, upgrading is a find & replace. Along with (hopefully) minor changes for when you have test helpers as methods or properties on your QuickSpec subclass. |
Thanks for your work @younata , this is huge. What a legend! 🔥 |
Awesome! Thanks! |
What did you do?
Tried upgrading to Quick 6.
What did you expect to happen?
Quick 6 has an incremental way of adopting concurrency and
toEventually
isn't broken in Objective-C.What actually happened instead?
Quick 6 added support for concurrency in a way that currently makes incremental adoption impossible.
The codebase that has to be upgraded to Quick 6 has a huge number specs across hundreds of modules and in order to upgrade all the problems introduced by the breaking changes have to be fixed in all those modules at once. Also generally the repo has a large amount of open PRs which would also need to be checked if they contain broken code and be fixed at the same time too.
Details:
Now tests run off the main thread (and off the MainActor) by default
To temporarily fix these each spec could be marked as
@MainActor
but that wouldn't solve the cases whereit
s orbeforeEach
s and its variants are used in a local function, since inside those the closures passed won't be@MainActor
:Another possible temporary solution is to mark all the
async
closures in all the specs@MainActor
but that would result in an immense amount of changes.Now the closures passed to
it
,beforeEach
and the variants of the latter are allasync
and there isn't a non-async alternativebecause of this (of course in addition to the above mentioned things) only the latest version of
Nimble
can be used which provides theasync
versions ofwaitUntil
,toEventually
and its variants and all the current usages can only be fixed all at oncethose are also used extensively and it's likely that numerous open PRs would also include new usages
toEventually
is broken in Objective-C because it runs in an async contextAdding this testcase to
FunctionalTests_ItSpec_ObjC
shows thattoEventually
is broken:Even though
World
hassyncIt
for Objective-C, the closures passed there are still executed in anasync
context, which brakestoEventually
as described here: Quick/Nimble#1007.What causes it to break is that the Objective-C blocks aren't
async
, so thenon-async
version oftoEventually
is used, which doesn't work in anasync
context, in which ultimately those blocks are executed, because of how the concurrency interoperability works between Objective-C and Swift.The Objective-C
QuickSpec
calls the synthesizedrunWithCompletionHandler
onExample
.runWithCompletionHandler
's implementation creates a detachedTask
in which it runsExample.run
and we end up in anasync
context. (https://github.com/apple/swift-evolution/blob/main/proposals/0297-concurrency-objc.md)I think to fix this a completely sync way of executing
Example
s still needs to exist besides the async, using which a better API that enables the incremental adoption of concurrency in Swift specs too could be implemented.Environment
The text was updated successfully, but these errors were encountered: