-
Notifications
You must be signed in to change notification settings - Fork 8
/
Copy pathflux.py
93 lines (64 loc) · 1.71 KB
/
flux.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
import unittest
from reobject.models import Model, Field
class Dispatcher(object):
stores = set()
@classmethod
def register(cls, store):
cls.stores.add(store)
@classmethod
def unregister(cls, store):
cls.stores.remove(store)
@classmethod
def dispatch(cls, action):
for store in cls.stores:
store.get_update_hook()(action)
dispatch = Dispatcher.dispatch
class Store(object):
_state = None
@classmethod
def get_state(cls):
return cls._state
@classmethod
def emit_change_event(cls):
raise NotImplementedError
@staticmethod
def reduce(state, action):
return state
@classmethod
def get_update_hook(cls):
def f(action):
new_state = cls.reduce(cls._state, action)
if new_state != cls._state:
cls._state = new_state
cls.emit_change_event()
return f
class Counter(Store):
_state = 0
@staticmethod
def reduce(state, action):
if action['type'] == 'INCREMENT':
return state + 1
else:
return state
@classmethod
def emit_change_event(cls):
for listener in View.objects.all():
listener()
def increment():
dispatch({
'type': 'INCREMENT'
})
class View(Model):
called = Field(default=0)
def __call__(self, *args, **kwargs):
self.called += 1
class TestFlux(unittest.TestCase):
@classmethod
def setUpClass(cls):
View()
Dispatcher.register(Counter)
def test_flux_increment(self):
increment()
increment()
assert View.objects.get().called == 2
assert Counter.get_state() == 2