-
Notifications
You must be signed in to change notification settings - Fork 95
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
Idea - Generic wait_until(predicate_func, timeout) & reaching max_time should fail the test & providing predicate functions like is_object_freed #585
Comments
I really like this idea. I guess the method would just be called in
I've often thought this too, but I think some I think some
await wait_until(has(vegetables_array, 'potato')) could be await assert_eventually_true(vegetables_array.has.bind('potato'), 5) I kinda like this await assert_eventually_eq(vegetables_array.size, 20, 5, 'we need 20 vegetables in 5 seconds or we did not do our job') Could there be a unwieldy generic # your example of
await wait_until(is_signal_connected(signaler, connector, 'the_signal'))
# could be something like this
await assert_eventually(
signaler.is_connected.bind('the_signal', connector.callback),
assert_signal_connected.bind(signaler, connector, 'the_signal'),
5,
'wait for it to be connected or 5 seconds, then assert it is connected') |
wait_XXXXXXXX shouldn't failAgreed. Very good point for the complex setup and not caring if the condition becomes true Naming it as wait_then_assert..... VS assert_eventually.....I like both. Small preference for assert_eventually(...) because it stands out from the never-failing wait_XXXXX functions. Generic assert_eventually(...)Yes to me it's a BIG plus if it's generic, because it lets users
Plus, you'll only need to define each predicate once and people can use them in many places
|
I'm not sure I understand the example here. It has 2 Callable predicates? |
The syntax might be slightly off, but the idea was to do the predicate thing with any assert passed as a await assert_eventually(
# predicate (Callable that is waited on until it returns true)
signaler.is_connected.bind('the_signal', connector.callback),
# An assert passed as Callable that will be run if the predicate
# returns true before timeout
assert_signal_connected.bind(signaler, connector, 'the_signal'),
# Max time in seconds to wait for predicate to return true,
# fails if timeout reached
5,
# Optional message to print
'wait for it to be connected or 5 seconds, then assert it is connected') |
Ok I understand now. I think having both a waiting function AND an asserting function makes it too complicated. In most cases, one could split it in two lines like this:
Predicate functions as a building blockI think this will help to implement this proposal and keep the GUT code & user tests simple. Inspiration
How to keep it DRY (pseudocode)
Usage
|
I think this is easy enough and we can do this right away. #New GUT public function
# This is what I actually need for my project 🎉
func assert_eventually(predicate_func, timeout) -> void:
var has_succeeded := await _has_successfully_waited_until(predicate_func, timeout)
if !has_succeeded :
fail('timed out after ', timeout, ' seconds') Breaking the asserts up will get a little messy. Messages change based on inputs, and we'd like to see those same outputs with Getting |
Great! Yeah the custom messages is gonna be tricky. Good point that we don't need to figure those yet for assert_eventually() to work. |
Based on everything else, I'm assuming you are wanting to implement this (which is great). I just wanted to confirm, so I don't get over-eager and start on it myself. After a quickish look, I think it would look like the following. This approach isn't written in stone, and somethings might be wrong. So let me know if you have any questions or issues.
|
Hit "comment" too soon. Here's some addition points of consideration.
|
Yes I'm happy to do it. Might take a while though, I'm just hobbying around. So if you get inspired feel free to do it! We can post progress here, whoever starts first :) |
Starting work on it |
Resolved by #609 @bitwes your Awaiter trick works. Let me know what you think 🤞 I called it I think we could merge it as is and iterate later as needed. |
Context
Awaiting provides wait_seconds, wait_frames and wait_for_signal, which are great.
A pattern that often comes up in my tests is to wait for a particular condition to be true.
For example
In all cases, if a certain timeout is reached, I want the test to fail.
Ideas
Generic
wait_until(predicate_func, timeout)
predicate_func
: Callable returning a boolean. Returns true when the success condition is reachedmax_wait
: same aswait_for_signal
. Timeout after which we stop blocking the testFail on max_time reached
I think
wait_for_signal
andwait_until
should fail the test when the max_time is reached, just like a failed assertion.is_object_freed predicate
GUT could provide a predicate function returning true when an object has been freed.
Other predicates
Many conditions used in assertions would be great as conditions to
wait_until
if they were converted into predicate functions (excuse the bad names hehe)Usage
Bonus idea: wait until freed
Here's a PR I made for wait_until_freed. Another way to wait until something is freed could be done with GUT just providing a predicate to check if something is freed.
The text was updated successfully, but these errors were encountered: