calculate.py 2.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106
  1. import pydux_thunk
  2. import asyncio
  3. initial_state = {
  4. 'running': False,
  5. 'result': None,
  6. 'error': None
  7. }
  8. class ActionTypes(object):
  9. START = 'calculate/START'
  10. FAILURE = 'calculate/FAILURE'
  11. SUCCESS = 'calculate/SUCCESS'
  12. class ActionCreators(object):
  13. @staticmethod
  14. def calculate(value1, value2):
  15. return thunk(value1, value2)
  16. @staticmethod
  17. def start():
  18. return dict(
  19. type=ActionTypes.START
  20. )
  21. @staticmethod
  22. def success(result):
  23. return dict(
  24. type=ActionTypes.SUCCESS,
  25. result=result
  26. )
  27. @staticmethod
  28. def failure(error):
  29. return dict(
  30. type=ActionTypes.FAILURE,
  31. error=error
  32. )
  33. def reducer(state=None, action=None):
  34. if state is None:
  35. state = initial_state
  36. if not (isinstance(action, dict) and 'type' in action):
  37. return state
  38. if action['type'] == ActionTypes.START:
  39. state['running'] = True
  40. elif action['type'] == ActionTypes.SUCCESS:
  41. state['running'] = False
  42. state['result'] = action['result']
  43. state['error'] = None
  44. elif action['type'] == ActionTypes.FAILURE:
  45. state['running'] = False
  46. state['result'] = None
  47. state['error'] = action['error']
  48. return state
  49. async def calculate(value1, value2):
  50. print('dividing', value1, value2)
  51. await asyncio.sleep(3)
  52. return value1 / value2
  53. def thunk(value1, value2):
  54. async def wrapper(dispatch, get_state):
  55. dispatch(ActionCreators.start())
  56. try:
  57. result = await calculate(value1, value2)
  58. dispatch(ActionCreators.success(result))
  59. except Exception as error:
  60. dispatch(ActionCreators.failure(dict(
  61. type=error.__class__.__name__,
  62. description=str(error)
  63. )))
  64. return wrapper
  65. if __name__ == '__main__':
  66. import unittest
  67. class TestSuite(unittest.TestCase):
  68. def test_action_creators(self):
  69. # self.assertEqual(ActionCreators.calculate(1, 2), thunk(1, 2))
  70. self.assertEqual(ActionCreators.start(), {'type': 'calculate/START'})
  71. self.assertEqual(ActionCreators.success(4), {'type': 'calculate/SUCCESS', 'result': 4})
  72. # self.assertEqual(ActionCreators.failure(ZeroDivisionError()), {'type': 'calculate/FAILURE', 'error': ZeroDivisionError()})
  73. def test_reducer(self):
  74. self.assertEqual(reducer(None, ActionCreators.calculate(2)),
  75. {'running': False, 'result': None, 'error': None})
  76. # self.assertEqual(reducer(452, ActionCreators.set_state(13)), 13)
  77. # self.assertEqual(reducer(None, ActionCreators.increment()), 1)
  78. # self.assertEqual(reducer(341, ActionCreators.increment()), 342)
  79. # self.assertEqual(reducer(None, ActionCreators.decrement()), -1)
  80. # self.assertEqual(reducer(251, ActionCreators.decrement()), 250)
  81. unittest.main()