1+ import { h , render } from 'preact' ;
2+ import { createStore , Provider , connect } from './unistore' ;
3+
4+ const sleep = ms => new Promise ( r => setTimeout ( r , ms ) ) ;
5+
6+ describe ( 'createStore()' , ( ) => {
7+ it ( 'should be instantiable' , ( ) => {
8+ let store = createStore ( ) ;
9+ expect ( store ) . toMatchObject ( {
10+ setState : expect . any ( Function ) ,
11+ getState : expect . any ( Function ) ,
12+ subscribe : expect . any ( Function ) ,
13+ unsubscribe : expect . any ( Function )
14+ } ) ;
15+ } ) ;
16+
17+ it ( 'should update state in-place' , ( ) => {
18+ let store = createStore ( ) ;
19+ expect ( store . getState ( ) ) . toMatchObject ( { } ) ;
20+ store . setState ( { a : 'b' } ) ;
21+ expect ( store . getState ( ) ) . toMatchObject ( { a : 'b' } ) ;
22+ store . setState ( { c : 'd' } ) ;
23+ expect ( store . getState ( ) ) . toMatchObject ( { a : 'b' , c : 'd' } ) ;
24+ store . setState ( { a : 'x' } ) ;
25+ expect ( store . getState ( ) ) . toMatchObject ( { a : 'x' , c : 'd' } ) ;
26+ store . setState ( { c : null } ) ;
27+ expect ( store . getState ( ) ) . toMatchObject ( { a : 'x' , c : null } ) ;
28+ store . setState ( { c : undefined } ) ;
29+ expect ( store . getState ( ) ) . toMatchObject ( { a : 'x' , c : undefined } ) ;
30+ } ) ;
31+
32+ it ( 'should invoke subscriptions' , ( ) => {
33+ let store = createStore ( ) ;
34+
35+ let sub1 = jest . fn ( ) ;
36+ let sub2 = jest . fn ( ) ;
37+
38+ let rval = store . subscribe ( sub1 ) ;
39+ expect ( rval ) . toBe ( undefined ) ;
40+
41+ store . setState ( { a : 'b' } ) ;
42+ expect ( sub1 ) . toBeCalledWith ( store . getState ( ) ) ;
43+
44+ store . subscribe ( sub2 ) ;
45+ store . setState ( { c : 'd' } ) ;
46+
47+ expect ( sub1 ) . toHaveBeenCalledTimes ( 2 ) ;
48+ expect ( sub1 ) . toHaveBeenLastCalledWith ( store . getState ( ) ) ;
49+ expect ( sub2 ) . toBeCalledWith ( store . getState ( ) ) ;
50+ } ) ;
51+
52+ it ( 'should unsubscribe' , ( ) => {
53+ let store = createStore ( ) ;
54+
55+ let sub1 = jest . fn ( ) ;
56+ let sub2 = jest . fn ( ) ;
57+
58+ store . subscribe ( sub1 ) ;
59+ store . subscribe ( sub2 ) ;
60+
61+ store . setState ( { a : 'b' } ) ;
62+ expect ( sub1 ) . toBeCalled ( ) ;
63+ expect ( sub2 ) . toBeCalled ( ) ;
64+
65+ sub1 . mockReset ( ) ;
66+ sub2 . mockReset ( ) ;
67+
68+ store . unsubscribe ( sub2 ) ;
69+
70+ store . setState ( { c : 'd' } ) ;
71+ expect ( sub1 ) . toBeCalled ( ) ;
72+ expect ( sub2 ) . not . toBeCalled ( ) ;
73+
74+ sub1 . mockReset ( ) ;
75+ sub2 . mockReset ( ) ;
76+
77+ store . unsubscribe ( sub1 ) ;
78+
79+ store . setState ( { e : 'f' } ) ;
80+ expect ( sub1 ) . not . toBeCalled ( ) ;
81+ expect ( sub2 ) . not . toBeCalled ( ) ;
82+ } ) ;
83+ } ) ;
84+
85+ describe ( '<Provider>' , ( ) => {
86+ it ( 'should provide props into context' , ( ) => {
87+ const Child = jest . fn ( ) ;
88+ let obj = { name : 'obj' } ;
89+ render ( < Provider a = "a" obj = { obj } > < Child /> </ Provider > , document . body ) ;
90+ expect ( Child ) . toHaveBeenCalledWith ( expect . anything ( ) , { a : 'a' , obj } ) ;
91+ } ) ;
92+ } ) ;
93+
94+ describe ( 'connect()' , ( ) => {
95+ it ( 'should pass mapped state as props' , ( ) => {
96+ let state = { a : 'b' } ;
97+ const store = { subscribe : jest . fn ( ) , getState : ( ) => state } ;
98+ const Child = jest . fn ( ) ;
99+ const ConnectedChild = connect ( Object ) ( Child ) ;
100+ render ( < Provider store = { store } > < ConnectedChild /> </ Provider > , document . body ) ;
101+ expect ( Child ) . toHaveBeenCalledWith ( { a : 'b' , store, children : expect . anything ( ) } , expect . anything ( ) ) ;
102+ expect ( store . subscribe ) . toBeCalled ( ) ;
103+ } ) ;
104+
105+ it ( 'should subscribe to store' , async ( ) => {
106+ const store = createStore ( ) ;
107+ const Child = jest . fn ( ) ;
108+ jest . spyOn ( store , 'subscribe' ) ;
109+ jest . spyOn ( store , 'unsubscribe' ) ;
110+ const ConnectedChild = connect ( Object ) ( Child ) ;
111+
112+ let root = render ( < Provider store = { store } > < ConnectedChild /> </ Provider > , document . body ) ;
113+
114+ expect ( store . subscribe ) . toBeCalledWith ( expect . any ( Function ) ) ;
115+ expect ( Child ) . toHaveBeenCalledWith ( { store, children : expect . anything ( ) } , expect . anything ( ) ) ;
116+
117+ Child . mockReset ( ) ;
118+
119+ store . setState ( { a : 'b' } ) ;
120+ await sleep ( 1 ) ;
121+ expect ( Child ) . toHaveBeenCalledWith ( { a : 'b' , store, children : expect . anything ( ) } , expect . anything ( ) ) ;
122+
123+ render ( null , document . body , root ) ;
124+ expect ( store . unsubscribe ) . toBeCalled ( ) ;
125+
126+ Child . mockReset ( ) ;
127+
128+ store . setState ( { c : 'd' } ) ;
129+ await sleep ( 1 ) ;
130+ expect ( Child ) . not . toHaveBeenCalled ( ) ;
131+ } ) ;
132+ } ) ;
0 commit comments