test_composed_behaviour.py 4.3KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166
  1. # coding: utf-8
  2. import typing
  3. from synergine2.config import Config
  4. from synergine2.simulation import SubjectComposedBehaviour
  5. from synergine2.simulation import BehaviourStep
  6. from synergine2.simulation import Event
  7. from synergine2_xyz.simulation import XYZSimulation
  8. from synergine2_xyz.subjects import XYZSubject
  9. from tests import BaseTest
  10. class BeginFirstEvent(Event):
  11. pass
  12. class FinishFirstEvent(Event):
  13. pass
  14. class BeginSecondEvent(Event):
  15. pass
  16. class FinishSecondEvent(Event):
  17. pass
  18. class BeginBaseEvent(Event):
  19. pass
  20. class FinishBaseEvent(Event):
  21. pass
  22. class MyFirstStep(BehaviourStep):
  23. def __init__(self, base: int, first: float=-0.5):
  24. self.base = base
  25. self.first = first
  26. def proceed(self) -> 'BehaviourStep':
  27. self.first += 0.5
  28. if self.first == 1:
  29. next_step = MySecondStep(
  30. base=self.base,
  31. )
  32. next_step.proceed()
  33. return next_step
  34. return self
  35. def generate_data(self) -> typing.Any:
  36. return {
  37. 'base': self.base,
  38. 'first': self.first,
  39. }
  40. def get_events(self) -> typing.List[Event]:
  41. if self.base == 0 and self.first == 0:
  42. return [BeginBaseEvent(), BeginFirstEvent()]
  43. if self.first == 0:
  44. return [BeginFirstEvent()]
  45. if self.first == 1:
  46. return [FinishFirstEvent(), BeginSecondEvent()]
  47. return []
  48. class MySecondStep(BehaviourStep):
  49. def __init__(self, base: int, second: float=-0.5):
  50. self.base = base
  51. self.second = second
  52. def proceed(self) -> 'BehaviourStep':
  53. self.second += 0.5
  54. if self.second == 1:
  55. self.base = 1
  56. return self
  57. def get_events(self) -> typing.List[Event]:
  58. if self.second == 0:
  59. return [BeginSecondEvent(), FinishFirstEvent()]
  60. if self.second == 1:
  61. return [FinishSecondEvent(), FinishBaseEvent()]
  62. return []
  63. def generate_data(self) -> typing.Any:
  64. return {
  65. 'base': self.base,
  66. 'second': self.second,
  67. }
  68. class MyComposedBehaviour(SubjectComposedBehaviour):
  69. step_classes = [
  70. (MySecondStep, lambda d: 'second' in d),
  71. (MyFirstStep, lambda d: 'first' in d or d.get('base') == 0),
  72. ]
  73. class TestComposedBehaviour(BaseTest):
  74. def test_subject_composed_behaviour(self):
  75. config = Config({})
  76. simulation = XYZSimulation(config)
  77. subject = XYZSubject(config, simulation)
  78. my_composed_behaviour = MyComposedBehaviour(
  79. config=config,
  80. simulation=simulation,
  81. subject=subject,
  82. )
  83. # Thirst cycle, ThirstStep is reached and produce event
  84. data = my_composed_behaviour.run({
  85. 'base': 0,
  86. })
  87. assert {'base': 0, 'first': 0} == data
  88. events = my_composed_behaviour.action(data)
  89. assert events
  90. assert 2 == len(events)
  91. assert isinstance(events[0], BeginBaseEvent)
  92. assert isinstance(events[1], BeginFirstEvent)
  93. # Second cycle (with previous cycle data), there is data but no events
  94. data = my_composed_behaviour.run(data)
  95. assert {'base': 0, 'first': 0.5} == data
  96. events = my_composed_behaviour.action(data)
  97. assert not events
  98. # Third cycle (still with previous cycle data) there is data but and events
  99. data = my_composed_behaviour.run(data)
  100. assert {'base': 0, 'second': 0} == data
  101. events = my_composed_behaviour.action(data)
  102. assert events
  103. assert 2 == len(events)
  104. assert isinstance(events[0], BeginSecondEvent)
  105. assert isinstance(events[1], FinishFirstEvent)
  106. # Fourth cycle (still with previous cycle data) there is data but no events
  107. data = my_composed_behaviour.run(data)
  108. assert {'base': 0, 'second': 0.5} == data
  109. events = my_composed_behaviour.action(data)
  110. assert not events
  111. # Cycle 5 (still with previous cycle data) there is data and events
  112. data = my_composed_behaviour.run(data)
  113. assert {'base': 1, 'second': 1} == data
  114. events = my_composed_behaviour.action(data)
  115. assert events
  116. assert 2 == len(events)
  117. assert isinstance(events[0], FinishSecondEvent)
  118. assert isinstance(events[1], FinishBaseEvent)