cooptools 1.65__tar.gz → 1.66__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (173) hide show
  1. {cooptools-1.65 → cooptools-1.66}/PKG-INFO +1 -1
  2. {cooptools-1.65 → cooptools-1.66}/cooptools/physics/kinematic_utils.py +8 -0
  3. {cooptools-1.65 → cooptools-1.66}/cooptools.egg-info/PKG-INFO +1 -1
  4. {cooptools-1.65 → cooptools-1.66}/setup.py +1 -1
  5. {cooptools-1.65 → cooptools-1.66}/tests/test_kinematic_utils.py +27 -0
  6. {cooptools-1.65 → cooptools-1.66}/tests/test_waypointFollower.py +18 -0
  7. {cooptools-1.65 → cooptools-1.66}/MANIFEST.in +0 -0
  8. {cooptools-1.65 → cooptools-1.66}/README.md +0 -0
  9. {cooptools-1.65 → cooptools-1.66}/cooptools/__init__.py +0 -0
  10. {cooptools-1.65 → cooptools-1.66}/cooptools/anchor.py +0 -0
  11. {cooptools-1.65 → cooptools-1.66}/cooptools/asyncable.py +0 -0
  12. {cooptools-1.65 → cooptools-1.66}/cooptools/cli/CliAtomicUserInteraction.py +0 -0
  13. {cooptools-1.65 → cooptools-1.66}/cooptools/cli/CliMenu.py +0 -0
  14. {cooptools-1.65 → cooptools-1.66}/cooptools/cli/__init__.py +0 -0
  15. {cooptools-1.65 → cooptools-1.66}/cooptools/cli/fileContentReturn.py +0 -0
  16. {cooptools-1.65 → cooptools-1.66}/cooptools/cnxn_info.py +0 -0
  17. {cooptools-1.65 → cooptools-1.66}/cooptools/colors.py +0 -0
  18. {cooptools-1.65 → cooptools-1.66}/cooptools/commandDesignPattern/__init__.py +0 -0
  19. {cooptools-1.65 → cooptools-1.66}/cooptools/commandDesignPattern/commandController.py +0 -0
  20. {cooptools-1.65 → cooptools-1.66}/cooptools/commandDesignPattern/commandProtocol.py +0 -0
  21. {cooptools-1.65 → cooptools-1.66}/cooptools/commandDesignPattern/exceptions.py +0 -0
  22. {cooptools-1.65 → cooptools-1.66}/cooptools/common.py +0 -0
  23. {cooptools-1.65 → cooptools-1.66}/cooptools/config.py +0 -0
  24. {cooptools-1.65 → cooptools-1.66}/cooptools/coopDataclass.py +0 -0
  25. {cooptools-1.65 → cooptools-1.66}/cooptools/coopEnum.py +0 -0
  26. {cooptools-1.65 → cooptools-1.66}/cooptools/coopthreading.py +0 -0
  27. {cooptools-1.65 → cooptools-1.66}/cooptools/currency.py +0 -0
  28. {cooptools-1.65 → cooptools-1.66}/cooptools/dataRefresher/__init__.py +0 -0
  29. {cooptools-1.65 → cooptools-1.66}/cooptools/dataRefresher/dataHub.py +0 -0
  30. {cooptools-1.65 → cooptools-1.66}/cooptools/dataRefresher/dataRefresher.py +0 -0
  31. {cooptools-1.65 → cooptools-1.66}/cooptools/dataStore/__init__.py +0 -0
  32. {cooptools-1.65 → cooptools-1.66}/cooptools/dataStore/dataProcessor.py +0 -0
  33. {cooptools-1.65 → cooptools-1.66}/cooptools/dataStore/dataStoreProtocol.py +0 -0
  34. {cooptools-1.65 → cooptools-1.66}/cooptools/dataStore/dbConnectionURI.py +0 -0
  35. {cooptools-1.65 → cooptools-1.66}/cooptools/dataStore/inMemoryDataStore.py +0 -0
  36. {cooptools-1.65 → cooptools-1.66}/cooptools/date_utils.py +0 -0
  37. {cooptools-1.65 → cooptools-1.66}/cooptools/decay.py +0 -0
  38. {cooptools-1.65 → cooptools-1.66}/cooptools/decor.py +0 -0
  39. {cooptools-1.65 → cooptools-1.66}/cooptools/dictPolicies.py +0 -0
  40. {cooptools-1.65 → cooptools-1.66}/cooptools/exceptions.py +0 -0
  41. {cooptools-1.65 → cooptools-1.66}/cooptools/expertise/__init__.py +0 -0
  42. {cooptools-1.65 → cooptools-1.66}/cooptools/expertise/expertiseArgs.py +0 -0
  43. {cooptools-1.65 → cooptools-1.66}/cooptools/expertise/expertiseSchedules.py +0 -0
  44. {cooptools-1.65 → cooptools-1.66}/cooptools/finance/__init__.py +0 -0
  45. {cooptools-1.65 → cooptools-1.66}/cooptools/finance/dicounted_cashflow_analysis.py +0 -0
  46. {cooptools-1.65 → cooptools-1.66}/cooptools/finance/fund_projection.py +0 -0
  47. {cooptools-1.65 → cooptools-1.66}/cooptools/finance/fund_projection_renderer.py +0 -0
  48. {cooptools-1.65 → cooptools-1.66}/cooptools/finance/futureValueProjector.py +0 -0
  49. {cooptools-1.65 → cooptools-1.66}/cooptools/finance/growth_projections.py +0 -0
  50. {cooptools-1.65 → cooptools-1.66}/cooptools/finance/reports.py +0 -0
  51. {cooptools-1.65 → cooptools-1.66}/cooptools/finance/utils.py +0 -0
  52. {cooptools-1.65 → cooptools-1.66}/cooptools/geometry_utils/__init__.py +0 -0
  53. {cooptools-1.65 → cooptools-1.66}/cooptools/geometry_utils/circle_utils.py +0 -0
  54. {cooptools-1.65 → cooptools-1.66}/cooptools/geometry_utils/common.py +0 -0
  55. {cooptools-1.65 → cooptools-1.66}/cooptools/geometry_utils/curve_utils.py +0 -0
  56. {cooptools-1.65 → cooptools-1.66}/cooptools/geometry_utils/line_utils.py +0 -0
  57. {cooptools-1.65 → cooptools-1.66}/cooptools/geometry_utils/polygon_utils.py +0 -0
  58. {cooptools-1.65 → cooptools-1.66}/cooptools/geometry_utils/rect_utils.py +0 -0
  59. {cooptools-1.65 → cooptools-1.66}/cooptools/geometry_utils/triangle_utils.py +0 -0
  60. {cooptools-1.65 → cooptools-1.66}/cooptools/geometry_utils/vector_utils.py +0 -0
  61. {cooptools-1.65 → cooptools-1.66}/cooptools/graphs/__init__.py +0 -0
  62. {cooptools-1.65 → cooptools-1.66}/cooptools/graphs/astar_results_viewer.py +0 -0
  63. {cooptools-1.65 → cooptools-1.66}/cooptools/graphs/draw.py +0 -0
  64. {cooptools-1.65 → cooptools-1.66}/cooptools/graphs/graph.py +0 -0
  65. {cooptools-1.65 → cooptools-1.66}/cooptools/graphs/graph_dcs.py +0 -0
  66. {cooptools-1.65 → cooptools-1.66}/cooptools/graphs/graph_definitions.py +0 -0
  67. {cooptools-1.65 → cooptools-1.66}/cooptools/graphs/utils.py +0 -0
  68. {cooptools-1.65 → cooptools-1.66}/cooptools/ideas/__init__.py +0 -0
  69. {cooptools-1.65 → cooptools-1.66}/cooptools/ideas/actionItemTracker/__init__.py +0 -0
  70. {cooptools-1.65 → cooptools-1.66}/cooptools/ideas/actionItemTracker/ai_tracker.py +0 -0
  71. {cooptools-1.65 → cooptools-1.66}/cooptools/ideas/actionItemTracker/dcs.py +0 -0
  72. {cooptools-1.65 → cooptools-1.66}/cooptools/ideas/discreteEventSimulator/__init__.py +0 -0
  73. {cooptools-1.65 → cooptools-1.66}/cooptools/ideas/discreteEventSimulator/discreteEventSimulator.py +0 -0
  74. {cooptools-1.65 → cooptools-1.66}/cooptools/ideas/jsonIO.py +0 -0
  75. {cooptools-1.65 → cooptools-1.66}/cooptools/ideas/metrics.py +0 -0
  76. {cooptools-1.65 → cooptools-1.66}/cooptools/ideas/triggerActionSystem/__init__.py +0 -0
  77. {cooptools-1.65 → cooptools-1.66}/cooptools/ideas/triggerActionSystem/signal.py +0 -0
  78. {cooptools-1.65 → cooptools-1.66}/cooptools/ideas/triggerActionSystem/trigger.py +0 -0
  79. {cooptools-1.65 → cooptools-1.66}/cooptools/loggingHelpers.py +0 -0
  80. {cooptools-1.65 → cooptools-1.66}/cooptools/marchingSquares.py +0 -0
  81. {cooptools-1.65 → cooptools-1.66}/cooptools/materialHandling/__init__.py +0 -0
  82. {cooptools-1.65 → cooptools-1.66}/cooptools/materialHandling/cli.py +0 -0
  83. {cooptools-1.65 → cooptools-1.66}/cooptools/materialHandling/dcs.py +0 -0
  84. {cooptools-1.65 → cooptools-1.66}/cooptools/materialHandling/selectionCriteria.py +0 -0
  85. {cooptools-1.65 → cooptools-1.66}/cooptools/matrixManipulation.py +0 -0
  86. {cooptools-1.65 → cooptools-1.66}/cooptools/os_manip.py +0 -0
  87. {cooptools-1.65 → cooptools-1.66}/cooptools/pandasHelpers.py +0 -0
  88. {cooptools-1.65 → cooptools-1.66}/cooptools/physics/__init__.py +0 -0
  89. {cooptools-1.65 → cooptools-1.66}/cooptools/physics/demo/__init__.py +0 -0
  90. {cooptools-1.65 → cooptools-1.66}/cooptools/physics/demo/server.py +0 -0
  91. {cooptools-1.65 → cooptools-1.66}/cooptools/physics/kinematic.py +0 -0
  92. {cooptools-1.65 → cooptools-1.66}/cooptools/physics/movement.py +0 -0
  93. {cooptools-1.65 → cooptools-1.66}/cooptools/physics/trajectory.py +0 -0
  94. {cooptools-1.65 → cooptools-1.66}/cooptools/physics/waypoint.py +0 -0
  95. {cooptools-1.65 → cooptools-1.66}/cooptools/physics/waypointFollower.py +0 -0
  96. {cooptools-1.65 → cooptools-1.66}/cooptools/plotting.py +0 -0
  97. {cooptools-1.65 → cooptools-1.66}/cooptools/printing.py +0 -0
  98. {cooptools-1.65 → cooptools-1.66}/cooptools/protocols.py +0 -0
  99. {cooptools-1.65 → cooptools-1.66}/cooptools/qualifiers/__init__.py +0 -0
  100. {cooptools-1.65 → cooptools-1.66}/cooptools/qualifiers/cli.py +0 -0
  101. {cooptools-1.65 → cooptools-1.66}/cooptools/qualifiers/qualifier.py +0 -0
  102. {cooptools-1.65 → cooptools-1.66}/cooptools/randoms.py +0 -0
  103. {cooptools-1.65 → cooptools-1.66}/cooptools/register.py +0 -0
  104. {cooptools-1.65 → cooptools-1.66}/cooptools/reservation/__init__.py +0 -0
  105. {cooptools-1.65 → cooptools-1.66}/cooptools/reservation/dcs.py +0 -0
  106. {cooptools-1.65 → cooptools-1.66}/cooptools/reservation/enums.py +0 -0
  107. {cooptools-1.65 → cooptools-1.66}/cooptools/reservation/reservationmanager.py +0 -0
  108. {cooptools-1.65 → cooptools-1.66}/cooptools/retry.py +0 -0
  109. {cooptools-1.65 → cooptools-1.66}/cooptools/sectors/__init__.py +0 -0
  110. {cooptools-1.65 → cooptools-1.66}/cooptools/sectors/grids/__init__.py +0 -0
  111. {cooptools-1.65 → cooptools-1.66}/cooptools/sectors/grids/gridState.py +0 -0
  112. {cooptools-1.65 → cooptools-1.66}/cooptools/sectors/grids/grid_base.py +0 -0
  113. {cooptools-1.65 → cooptools-1.66}/cooptools/sectors/grids/hexGrid.py +0 -0
  114. {cooptools-1.65 → cooptools-1.66}/cooptools/sectors/grids/rectGrid.py +0 -0
  115. {cooptools-1.65 → cooptools-1.66}/cooptools/sectors/hex_utils.py +0 -0
  116. {cooptools-1.65 → cooptools-1.66}/cooptools/sectors/sect_utils.py +0 -0
  117. {cooptools-1.65 → cooptools-1.66}/cooptools/sectors/sectorTree/__init__.py +0 -0
  118. {cooptools-1.65 → cooptools-1.66}/cooptools/sectors/sectorTree/sectorTree.py +0 -0
  119. {cooptools-1.65 → cooptools-1.66}/cooptools/statistics/__init__.py +0 -0
  120. {cooptools-1.65 → cooptools-1.66}/cooptools/statistics/activityReport.py +0 -0
  121. {cooptools-1.65 → cooptools-1.66}/cooptools/statistics/controlChart/__init__.py +0 -0
  122. {cooptools-1.65 → cooptools-1.66}/cooptools/statistics/controlChart/controlChart.py +0 -0
  123. {cooptools-1.65 → cooptools-1.66}/cooptools/statistics/controlChart/plotting.py +0 -0
  124. {cooptools-1.65 → cooptools-1.66}/cooptools/statistics/oee/__init__.py +0 -0
  125. {cooptools-1.65 → cooptools-1.66}/cooptools/statistics/oee/oeeHub.py +0 -0
  126. {cooptools-1.65 → cooptools-1.66}/cooptools/taskProcessing/__init__.py +0 -0
  127. {cooptools-1.65 → cooptools-1.66}/cooptools/taskProcessing/dcs.py +0 -0
  128. {cooptools-1.65 → cooptools-1.66}/cooptools/taskProcessing/taskProcessor.py +0 -0
  129. {cooptools-1.65 → cooptools-1.66}/cooptools/timeTracker/__init__.py +0 -0
  130. {cooptools-1.65 → cooptools-1.66}/cooptools/timeTracker/decay.py +0 -0
  131. {cooptools-1.65 → cooptools-1.66}/cooptools/timeTracker/timeTracker.py +0 -0
  132. {cooptools-1.65 → cooptools-1.66}/cooptools/timeWindow.py +0 -0
  133. {cooptools-1.65 → cooptools-1.66}/cooptools/toggles.py +0 -0
  134. {cooptools-1.65 → cooptools-1.66}/cooptools/transform.py +0 -0
  135. {cooptools-1.65 → cooptools-1.66}/cooptools/trends.py +0 -0
  136. {cooptools-1.65 → cooptools-1.66}/cooptools/typeProviders.py +0 -0
  137. {cooptools-1.65 → cooptools-1.66}/cooptools/typevalidation.py +0 -0
  138. {cooptools-1.65 → cooptools-1.66}/cooptools/version.py +0 -0
  139. {cooptools-1.65 → cooptools-1.66}/cooptools.egg-info/SOURCES.txt +0 -0
  140. {cooptools-1.65 → cooptools-1.66}/cooptools.egg-info/dependency_links.txt +0 -0
  141. {cooptools-1.65 → cooptools-1.66}/cooptools.egg-info/not-zip-safe +0 -0
  142. {cooptools-1.65 → cooptools-1.66}/cooptools.egg-info/requires.txt +0 -0
  143. {cooptools-1.65 → cooptools-1.66}/cooptools.egg-info/top_level.txt +0 -0
  144. {cooptools-1.65 → cooptools-1.66}/requirements.txt +0 -0
  145. {cooptools-1.65 → cooptools-1.66}/setup.cfg +0 -0
  146. {cooptools-1.65 → cooptools-1.66}/tests/test_CliAtomicUserInteraction.py +0 -0
  147. {cooptools-1.65 → cooptools-1.66}/tests/test_asyncable.py +0 -0
  148. {cooptools-1.65 → cooptools-1.66}/tests/test_cdp_bugs.py +0 -0
  149. {cooptools-1.65 → cooptools-1.66}/tests/test_commandDesignPattern.py +0 -0
  150. {cooptools-1.65 → cooptools-1.66}/tests/test_common.py +0 -0
  151. {cooptools-1.65 → cooptools-1.66}/tests/test_config.py +0 -0
  152. {cooptools-1.65 → cooptools-1.66}/tests/test_coopEnum.py +0 -0
  153. {cooptools-1.65 → cooptools-1.66}/tests/test_currency.py +0 -0
  154. {cooptools-1.65 → cooptools-1.66}/tests/test_date_utils.py +0 -0
  155. {cooptools-1.65 → cooptools-1.66}/tests/test_fund_projection.py +0 -0
  156. {cooptools-1.65 → cooptools-1.66}/tests/test_kinematic.py +0 -0
  157. {cooptools-1.65 → cooptools-1.66}/tests/test_os_manip.py +0 -0
  158. {cooptools-1.65 → cooptools-1.66}/tests/test_pandas.py +0 -0
  159. {cooptools-1.65 → cooptools-1.66}/tests/test_printing.py +0 -0
  160. {cooptools-1.65 → cooptools-1.66}/tests/test_qualifiers.py +0 -0
  161. {cooptools-1.65 → cooptools-1.66}/tests/test_sectors.py +0 -0
  162. {cooptools-1.65 → cooptools-1.66}/tests/test_sectors_hex.py +0 -0
  163. {cooptools-1.65 → cooptools-1.66}/tests/test_sectors_sectorTree.py +0 -0
  164. {cooptools-1.65 → cooptools-1.66}/tests/test_statistics.py +0 -0
  165. {cooptools-1.65 → cooptools-1.66}/tests/test_tasks.py +0 -0
  166. {cooptools-1.65 → cooptools-1.66}/tests/test_toggles.py +0 -0
  167. {cooptools-1.65 → cooptools-1.66}/tests/test_trajectory.py +0 -0
  168. {cooptools-1.65 → cooptools-1.66}/tests/test_trends.py +0 -0
  169. {cooptools-1.65 → cooptools-1.66}/tests/test_typevalidation.py +0 -0
  170. {cooptools-1.65 → cooptools-1.66}/tests/test_vector_utils.py +0 -0
  171. {cooptools-1.65 → cooptools-1.66}/tests/test_version.py +0 -0
  172. {cooptools-1.65 → cooptools-1.66}/tests/tests_graph.py +0 -0
  173. {cooptools-1.65 → cooptools-1.66}/tests/tests_gridsystem.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: cooptools
3
- Version: 1.65
3
+ Version: 1.66
4
4
  Summary: Generic Tooling
5
5
  Home-page: https://github.com/tylertjburns/cooptools
6
6
  Author: tburns
@@ -182,8 +182,16 @@ def _tick_accel_from_profile(profile: Tuple[PhaseResult, ...], dt: float) -> flo
182
182
  many phases fit within dt so the tick's velocity change matches the true profile
183
183
  instead of overshooting by committing the whole tick to one extreme.
184
184
  """
185
+ if dt < 0:
186
+ raise ValueError(f"_tick_accel_from_profile: dt must be >= 0, got {dt}")
185
187
  if not profile:
186
188
  return 0.0
189
+ if dt == 0:
190
+ # No time elapses this tick (e.g. delta_time_ms=0 for a position-only /
191
+ # realign update) -- the time-weighted average has no window to average
192
+ # over, so fall back to the instantaneous decision: the first phase's
193
+ # acceleration, which is what the weighted average converges to as dt -> 0+.
194
+ return profile[0].accel
187
195
  remaining = dt
188
196
  weighted = 0.0
189
197
  for phase in profile:
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: cooptools
3
- Version: 1.65
3
+ Version: 1.66
4
4
  Summary: Generic Tooling
5
5
  Home-page: https://github.com/tylertjburns/cooptools
6
6
  Author: tburns
@@ -7,7 +7,7 @@ with open('requirements.txt') as f:
7
7
  requirements = f.read().splitlines()
8
8
 
9
9
  setuptools.setup(name='cooptools',
10
- version='1.65',
10
+ version='1.66',
11
11
  description='Generic Tooling',
12
12
  url='https://github.com/tylertjburns/cooptools',
13
13
  author='tburns',
@@ -71,6 +71,18 @@ class Test_AxisArrivalAccel(unittest.TestCase):
71
71
  self.assertNotEqual(result, a) # not the naive "just keep accelerating" answer
72
72
  self.assertLess(result, a)
73
73
 
74
+ def test__dt_zero__in_braking_regime__does_not_raise_and_returns_brake(self):
75
+ # regression: a position-only update (delta_time_ms=0, e.g. a waypoint
76
+ # realign) while already past the switching threshold used to fall through
77
+ # to single_axis_motion_profile + _tick_accel_from_profile(profile, dt=0),
78
+ # which raised ZeroDivisionError. d=10, v=20, a=5 is the same past-threshold
79
+ # state as test__well_past_stopping_distance__brakes above.
80
+ result = kin._axis_arrival_accel(d=10, v=20, a=5, dt=0)
81
+ self.assertEqual(result, -5.0)
82
+
83
+ def test__dt_zero__in_cheap_accelerate_regime__still_accelerates(self):
84
+ self.assertEqual(kin._axis_arrival_accel(d=1000, v=1, a=5, dt=0), 5.0)
85
+
74
86
 
75
87
  class Test_TickAccelFromProfile(unittest.TestCase):
76
88
  """Direct unit coverage for the tick-blending helper in isolation, using
@@ -100,6 +112,21 @@ class Test_TickAccelFromProfile(unittest.TestCase):
100
112
  result = kin._tick_accel_from_profile((p1,), dt=0.03)
101
113
  self.assertAlmostEqual(result, (-8.0 * 0.01) / 0.03, places=9)
102
114
 
115
+ def test__dt_zero__non_empty_profile__returns_first_phase_accel_without_dividing_by_zero(self):
116
+ # regression: dt=0 (e.g. a position-only / realign update with
117
+ # delta_time_ms=0) used to divide weighted-by-zero into a ZeroDivisionError.
118
+ p1 = kin.PhaseResult(length=0, time=0.01, label="brake", accel=-8.0)
119
+ p2 = kin.PhaseResult(length=0, time=5.0, label="accel", accel=3.0)
120
+ self.assertEqual(kin._tick_accel_from_profile((p1, p2), dt=0), -8.0)
121
+
122
+ def test__dt_zero__empty_profile__returns_zero(self):
123
+ self.assertEqual(kin._tick_accel_from_profile((), dt=0), 0.0)
124
+
125
+ def test__dt_negative__raises_value_error(self):
126
+ p1 = kin.PhaseResult(length=0, time=0.01, label="brake", accel=-8.0)
127
+ with self.assertRaises(ValueError):
128
+ kin._tick_accel_from_profile((p1,), dt=-0.01)
129
+
103
130
 
104
131
  class Test_ArrivalAcceleration(unittest.TestCase):
105
132
  """Direct unit coverage for the multi-axis wrapper around _axis_arrival_accel."""
@@ -285,6 +285,24 @@ class Test_WaypointFollower_RealignToNextWaypoint(unittest.TestCase):
285
285
  self.assertEqual(follower.Position, (2.0, 100.0))
286
286
  self.assertEqual(follower.Velocity.CurrentVelocity_M_S, (1000.0, 0.0))
287
287
 
288
+ def test__update__delta_time_ms_zero__realign_to_next_waypoint__does_not_raise(self):
289
+ # regression: a position-only update (delta_time_ms=0, e.g. a caller placing
290
+ # a mover or re-issuing a route without advancing time) while braking toward
291
+ # a destination used to raise ZeroDivisionError from deep inside
292
+ # arrival_acceleration -> _axis_arrival_accel -> _tick_accel_from_profile,
293
+ # which divided a time-weighted acceleration by dt=0.
294
+ follower = _make_follower()
295
+ follower.add_waypoints([Waypoint(end_pos=(0, 100), is_destination=True)])
296
+ follower._goal_seeker.set_velocity((0, 60)) # fast enough to be past the
297
+ # switching threshold this close
298
+
299
+ # act -- must not raise
300
+ reached = follower.update(delta_time_ms=0, realign_to_next_waypoint=True)
301
+
302
+ # assert -- no time elapsed, so nothing moved and nothing was reached
303
+ self.assertEqual(reached, [])
304
+ self.assertEqual(follower.Position, (0.0, 0.0))
305
+
288
306
 
289
307
  class Test_WaypointFollower_DistanceToNextDestination(unittest.TestCase):
290
308
 
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes