[Merged by Bors] - Make Time::update_with_instant public for use in tests#4469
[Merged by Bors] - Make Time::update_with_instant public for use in tests#4469mdickopp wants to merge 6 commits intobevyengine:mainfrom mdickopp:pub_update_with_instant
Time::update_with_instant public for use in tests#4469Conversation
| /// 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.
| /// 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.
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.
#[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.
@mockersf, I agree with @alice-i-cecile. Is it acceptable to you to leave the patch unchanged?
There was a problem hiding this comment.
#[cfg(test)] only applies when testing the current crate, not when testing a dependent crate.
There was a problem hiding this comment.
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. |
maniwani
left a comment
There was a problem hiding this comment.
@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.
| /// 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.
Thank you for the suggestion! I updated the documentation accordingly.
There was a problem hiding this comment.
Can you add the second sentence ("Calling this...") as a disclaimer to Time::update as well?
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.
I suggest moving this doc test to update_with_instant.
There was a problem hiding this comment.
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 <martin@zero-based.org>
|
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 <martin@zero-based.org>
|
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 <martin@zero-based.org>
|
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 <martin@zero-based.org>
|
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 <martin@zero-based.org>
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 <martin@zero-based.org>
…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 <martin@zero-based.org> (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 <martin@zero-based.org>
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 anInstantdefined by the developer. This can be achieved by making the existingTime::update_with_instantmethod public for use in tests.Changelog
Time::update_with_instantpublicTime::update_with_instantclarifying that the method should not be called outside of tests.Timedemonstrating how to useupdate_with_instantin tests.