-
-
Notifications
You must be signed in to change notification settings - Fork 3.7k
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 by Bors] - Make Time::update_with_instant
public for use in tests
#4469
Conversation
crates/bevy_core/src/time/time.rs
Outdated
/// Update time with a specified [`Instant`] | ||
/// | ||
/// This method is for use in tests, and should generally not be called on the [`Time`] resource | ||
/// as part of your app. Doing so will conflict with the `time_system` called by | ||
/// [`CorePlugin`](crate::CorePlugin), and result in inaccurate performance measurements. | ||
pub fn update_with_instant(&mut self, instant: Instant) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
/// Update time with a specified [`Instant`] | |
/// | |
/// This method is for use in tests, and should generally not be called on the [`Time`] resource | |
/// as part of your app. Doing so will conflict with the `time_system` called by | |
/// [`CorePlugin`](crate::CorePlugin), and result in inaccurate performance measurements. | |
pub fn update_with_instant(&mut self, instant: Instant) { | |
/// Update time with a specified [`Instant`] | |
/// | |
/// This method is for use in tests, and should generally not be called on the [`Time`] resource | |
/// as part of your app. Doing so will conflict with the `time_system` called by | |
/// [`CorePlugin`](crate::CorePlugin), and result in inaccurate performance measurements. | |
#[cfg(test)] | |
pub fn manual_update_with_instant(&mut self, instant: Instant) { | |
self.update_with_instant(instant); | |
} | |
pub(crate) fn update_with_instant(&mut self, instant: Instant) { |
not sure this is a good idea, but it would make it impossible to mess with time. Doc comment above would need to be updated too
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
TBH I don't think this actually adds much more safety. I think that aggressive doc warnings should be sufficient here.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
#[cfg(test)]
hides the method from the new doctest. And #[cfg(doctest)]
does not work here due to a bug in cargo (rust-lang/rust#67295). Any ideas how this could be solved?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@mockersf, I agree with @alice-i-cecile. Is it acceptable to you to leave the patch unchanged?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
#[cfg(test)]
only applies when testing the current crate, not when testing a dependent crate.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It's acceptable, even more with Bjorn3 remark! (we already had this discussion on another place, and I keep forgetting that...).
It's not something I wanted to block on anyway
I see two options, either leave the patch unchanged, or add the Instead of removing the code in the doctest entirely, I would transform it into an example. |
My preference is for the former: I don't think the API is so dangerous that we need to hide it. |
Time::update_with_instant
public for use in tests
@mockersf, do you require code changes? |
@maniwani are you on board with merging this? I saw you mention it on Discord, and want your opinion. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@maniwani are you on board with merging this?
Yeah, I'm cool with making this method pub
. Nothing was stopping someone from calling Time::update
before.
A couple tiny nits. Also you should probably have the note saying the CorePlugin
is usually in charge on the update
doc as well.
crates/bevy_core/src/time/time.rs
Outdated
/// This method is for use in tests, and should generally not be called on the [`Time`] resource | ||
/// as part of your app. Doing so will conflict with the `time_system` called by | ||
/// [`CorePlugin`](crate::CorePlugin), and result in inaccurate performance measurements. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
/// This method is for use in tests, and should generally not be called on the [`Time`] resource | |
/// as part of your app. Doing so will conflict with the `time_system` called by | |
/// [`CorePlugin`](crate::CorePlugin), and result in inaccurate performance measurements. | |
/// This method is provided for use in tests. Calling this method on the [`Time`] resource as part of your app | |
/// will most likely result in inaccurate timekeeping, as the resource is ordinarily managed by the [`CorePlugin`](crate::CorePlugin). |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thank you for the suggestion! I updated the documentation accordingly.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can you add the second sentence ("Calling this...") as a disclaimer to Time::update
as well?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Good idea, agreed.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Sure. Done!
crates/bevy_core/src/time/time.rs
Outdated
/// ``` | ||
/// # use bevy_core::prelude::*; | ||
/// # use bevy_ecs::prelude::*; | ||
/// # use bevy_utils::Duration; | ||
/// # fn main () { | ||
/// # test_health_system(); | ||
/// # } | ||
/// struct Health { | ||
/// // Health value between 0.0 and 1.0 | ||
/// health_value: f32, | ||
/// } | ||
/// | ||
/// fn health_system(time: Res<Time>, mut health: ResMut<Health>) { | ||
/// // Increase health value by 0.1 per second, independent of frame rate, | ||
/// // but not beyond 1.0 | ||
/// health.health_value = (health.health_value + 0.1 * time.delta_seconds()).min(1.0); | ||
/// } | ||
/// | ||
/// // Mock time in tests | ||
/// fn test_health_system() { | ||
/// let mut world = World::default(); | ||
/// let mut time = Time::default(); | ||
/// time.update(); | ||
/// world.insert_resource(time); | ||
/// world.insert_resource(Health { health_value: 0.2 }); | ||
/// | ||
/// let mut update_stage = SystemStage::single_threaded(); | ||
/// update_stage.add_system(health_system); | ||
/// | ||
/// // Simulate that 30 ms have passed | ||
/// let mut time = world.get_resource_mut::<Time>().unwrap(); | ||
/// let last_update = time.last_update().unwrap(); | ||
/// time.update_with_instant(last_update + Duration::from_millis(30)); | ||
/// | ||
/// // Run system | ||
/// update_stage.run(&mut world); | ||
/// | ||
/// // Check that 0.003 has been added to the health value | ||
/// let expected_health_value = 0.2 + 0.1 * 0.03; | ||
/// let actual_health_value = world.get_resource::<Health>().unwrap().health_value; | ||
/// assert_eq!(expected_health_value, actual_health_value); | ||
/// } | ||
/// ``` |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I suggest moving this doc test to update_with_instant
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I moved the doc test,and I also replaced world.get_resource_mut::<Time>().unwrap()
with the simpler world.resource_mut::<Time>()
.
I'm confused by the CI failure, as I didn't change any markdown documents. Any advice would be appreciated. |
This is just a flaky CI failure @mdickopp, don't worry about it. |
bors r+ |
# Objective To test systems that implement frame rate-independent update logic, one needs to be able to mock `Time`. By mocking time, it's possible to write tests that confirm systems are frame rate-independent. This is a follow-up PR to #2549 by @ostwilkens and based on his work. ## Solution To mock `Time`, one needs to be able to manually update the Time resource with an `Instant` defined by the developer. This can be achieved by making the existing `Time::update_with_instant` method public for use in tests. ## Changelog - Make `Time::update_with_instant` public - Add doc to `Time::update_with_instant` clarifying that the method should not be called outside of tests. - Add doc test to `Time` demonstrating how to use `update_with_instant` in tests. Co-authored-by: Martin Dickopp <[email protected]>
Build failed: |
bors retry |
# Objective To test systems that implement frame rate-independent update logic, one needs to be able to mock `Time`. By mocking time, it's possible to write tests that confirm systems are frame rate-independent. This is a follow-up PR to #2549 by @ostwilkens and based on his work. ## Solution To mock `Time`, one needs to be able to manually update the Time resource with an `Instant` defined by the developer. This can be achieved by making the existing `Time::update_with_instant` method public for use in tests. ## Changelog - Make `Time::update_with_instant` public - Add doc to `Time::update_with_instant` clarifying that the method should not be called outside of tests. - Add doc test to `Time` demonstrating how to use `update_with_instant` in tests. Co-authored-by: Martin Dickopp <[email protected]>
Build failed: |
bors r+ |
# Objective To test systems that implement frame rate-independent update logic, one needs to be able to mock `Time`. By mocking time, it's possible to write tests that confirm systems are frame rate-independent. This is a follow-up PR to #2549 by @ostwilkens and based on his work. ## Solution To mock `Time`, one needs to be able to manually update the Time resource with an `Instant` defined by the developer. This can be achieved by making the existing `Time::update_with_instant` method public for use in tests. ## Changelog - Make `Time::update_with_instant` public - Add doc to `Time::update_with_instant` clarifying that the method should not be called outside of tests. - Add doc test to `Time` demonstrating how to use `update_with_instant` in tests. Co-authored-by: Martin Dickopp <[email protected]>
Build failed: |
bors r+ |
# Objective To test systems that implement frame rate-independent update logic, one needs to be able to mock `Time`. By mocking time, it's possible to write tests that confirm systems are frame rate-independent. This is a follow-up PR to #2549 by @ostwilkens and based on his work. ## Solution To mock `Time`, one needs to be able to manually update the Time resource with an `Instant` defined by the developer. This can be achieved by making the existing `Time::update_with_instant` method public for use in tests. ## Changelog - Make `Time::update_with_instant` public - Add doc to `Time::update_with_instant` clarifying that the method should not be called outside of tests. - Add doc test to `Time` demonstrating how to use `update_with_instant` in tests. Co-authored-by: Martin Dickopp <[email protected]>
Timed out. |
bors r+ |
# Objective To test systems that implement frame rate-independent update logic, one needs to be able to mock `Time`. By mocking time, it's possible to write tests that confirm systems are frame rate-independent. This is a follow-up PR to #2549 by @ostwilkens and based on his work. ## Solution To mock `Time`, one needs to be able to manually update the Time resource with an `Instant` defined by the developer. This can be achieved by making the existing `Time::update_with_instant` method public for use in tests. ## Changelog - Make `Time::update_with_instant` public - Add doc to `Time::update_with_instant` clarifying that the method should not be called outside of tests. - Add doc test to `Time` demonstrating how to use `update_with_instant` in tests. Co-authored-by: Martin Dickopp <[email protected]>
Time::update_with_instant
public for use in testsTime::update_with_instant
public for use in tests
Thanks! |
…4469) # Objective To test systems that implement frame rate-independent update logic, one needs to be able to mock `Time`. By mocking time, it's possible to write tests that confirm systems are frame rate-independent. This is a follow-up PR to bevyengine#2549 by @ostwilkens and based on his work. ## Solution To mock `Time`, one needs to be able to manually update the Time resource with an `Instant` defined by the developer. This can be achieved by making the existing `Time::update_with_instant` method public for use in tests. ## Changelog - Make `Time::update_with_instant` public - Add doc to `Time::update_with_instant` clarifying that the method should not be called outside of tests. - Add doc test to `Time` demonstrating how to use `update_with_instant` in tests. Co-authored-by: Martin Dickopp <[email protected]>
…4469) # Objective To test systems that implement frame rate-independent update logic, one needs to be able to mock `Time`. By mocking time, it's possible to write tests that confirm systems are frame rate-independent. This is a follow-up PR to bevyengine#2549 by @ostwilkens and based on his work. ## Solution To mock `Time`, one needs to be able to manually update the Time resource with an `Instant` defined by the developer. This can be achieved by making the existing `Time::update_with_instant` method public for use in tests. ## Changelog - Make `Time::update_with_instant` public - Add doc to `Time::update_with_instant` clarifying that the method should not be called outside of tests. - Add doc test to `Time` demonstrating how to use `update_with_instant` in tests. Co-authored-by: Martin Dickopp <[email protected]> (cherry picked from commit 93cee3b)
…4469) # Objective To test systems that implement frame rate-independent update logic, one needs to be able to mock `Time`. By mocking time, it's possible to write tests that confirm systems are frame rate-independent. This is a follow-up PR to bevyengine#2549 by @ostwilkens and based on his work. ## Solution To mock `Time`, one needs to be able to manually update the Time resource with an `Instant` defined by the developer. This can be achieved by making the existing `Time::update_with_instant` method public for use in tests. ## Changelog - Make `Time::update_with_instant` public - Add doc to `Time::update_with_instant` clarifying that the method should not be called outside of tests. - Add doc test to `Time` demonstrating how to use `update_with_instant` in tests. Co-authored-by: Martin Dickopp <[email protected]>
Objective
To test systems that implement frame rate-independent update logic, one needs to be able to mock
Time
. By mocking time, it's possible to write tests that confirm systems are frame rate-independent.This is a follow-up PR to #2549 by @ostwilkens and based on his work.
Solution
To mock
Time
, one needs to be able to manually update the Time resource with anInstant
defined by the developer. This can be achieved by making the existingTime::update_with_instant
method public for use in tests.Changelog
Time::update_with_instant
publicTime::update_with_instant
clarifying that the method should not be called outside of tests.Time
demonstrating how to useupdate_with_instant
in tests.