@@ -123,6 +123,130 @@ describe("Machine with entry and exit actions", () => {
123123 } ) ;
124124} ) ;
125125
126+ describe . skip ( "Fetch with abort signal" , ( ) => {
127+ const someURL = new URL ( "https://example.org/" ) ;
128+ function fetchData ( ) {
129+ return fetch ( someURL . toString ( ) ) ;
130+ }
131+
132+ function Loader ( ) {
133+ const aborterKey = Symbol ( 'aborter' ) ;
134+ // yield register(aborterKey, () => new AbortController());
135+ // yield register(function aborter() { return new AbortController() });
136+
137+ function * idle ( ) {
138+ yield on ( "FETCH" , loading ) ;
139+ }
140+ function * loading ( ) {
141+ // yield entry(aborterKey);
142+
143+ yield entry ( fetchData ) ;
144+ yield exit ( finishedLoading ) ;
145+ yield on ( "SUCCESS" , success ) ;
146+ yield on ( "FAILURE" , failure ) ;
147+ // yield forward(AbortController.prototype.abort, aborter);
148+ // yield forward("abort", aborter);
149+ // yield forward("CANCEL", aborter);
150+ // yield forward("CANCEL", aborterKey);
151+ }
152+ function * success ( ) {
153+ yield entry ( succeeded ) ;
154+ }
155+ function * failure ( ) {
156+ yield on ( "RETRY" , loading ) ;
157+ }
158+
159+ return idle ;
160+ }
161+
162+ test ( "creating" , ( ) => {
163+ const loader = start ( Loader ) ;
164+ expect ( loader ) . toBeDefined ( ) ;
165+ } ) ;
166+
167+ describe ( "when fetch succeeds" , ( ) => {
168+ beforeEach ( ( ) => {
169+ fetch . mockResolvedValue ( 42 ) ;
170+ } ) ;
171+
172+ test ( "sending events" , async ( ) => {
173+ const loader = start ( Loader ) ;
174+ expect ( loader . current ) . toEqual ( "idle" ) ;
175+ expect ( loader . changeCount ) . toEqual ( 0 ) ;
176+
177+ loader . next ( "NOOP" ) ;
178+ expect ( loader . current ) . toEqual ( "idle" ) ;
179+ expect ( loader . changeCount ) . toEqual ( 0 ) ;
180+
181+ const transitionResult = loader . next ( "FETCH" ) ;
182+ expect ( fetch ) . toHaveBeenCalledWith ( "https://example.org/" ) ;
183+ expect ( transitionResult . actions ) . toEqual ( [
184+ { type : "entry" , f : fetchData } ,
185+ ] ) ;
186+ expect ( loader . current ) . toEqual ( "loading" ) ;
187+ expect ( loader . changeCount ) . toEqual ( 1 ) ;
188+ expect ( finishedLoading ) . toHaveBeenCalledTimes ( 0 ) ;
189+
190+ await expect ( loader . results ) . resolves . toEqual ( { fetchData : 42 } ) ;
191+ await expect ( Promise . resolve ( transitionResult ) ) . resolves . toEqual ( { fetchData : 42 } ) ;
192+ expect ( finishedLoading ) . toHaveBeenCalledTimes ( 1 ) ;
193+ expect ( loader . changeCount ) . toEqual ( 2 ) ;
194+ expect ( loader . current ) . toEqual ( "success" ) ;
195+ expect ( succeeded ) . toHaveBeenCalledTimes ( 1 ) ;
196+
197+ const transitionResult2 = loader . next ( "FETCH" ) ;
198+ // expect(transitionResult2.actions).toEqual([]);
199+ expect ( loader . changeCount ) . toEqual ( 2 ) ;
200+ expect ( loader . current ) . toEqual ( "success" ) ;
201+ expect ( succeeded ) . toHaveBeenCalledTimes ( 1 ) ;
202+
203+ await loader . results ;
204+ } ) ;
205+ } ) ;
206+
207+ describe ( "when fetch fails" , ( ) => {
208+ beforeEach ( ( ) => {
209+ fetch . mockRejectedValueOnce ( new Error ( "Failed!" ) ) . mockResolvedValue ( 42 ) ;
210+ } ) ;
211+
212+ test ( "sending events" , async ( ) => {
213+ const loader = start ( Loader ) ;
214+ expect ( loader . current ) . toEqual ( "idle" ) ;
215+
216+ const transitionResult = loader . next ( "FETCH" ) ;
217+ expect ( fetch ) . toHaveBeenCalledTimes ( 1 ) ;
218+ expect ( fetch ) . toHaveBeenLastCalledWith ( "https://example.org/" ) ;
219+ expect ( transitionResult . actions ) . toEqual ( [
220+ { type : "entry" , f : fetchData } ,
221+ ] ) ;
222+ expect ( loader . current ) . toEqual ( "loading" ) ;
223+ expect ( loader . changeCount ) . toEqual ( 1 ) ;
224+
225+ await expect ( loader . results ) . rejects . toEqual ( new Error ( "Failed!" ) ) ;
226+ await expect ( Promise . resolve ( transitionResult ) ) . rejects . toEqual (
227+ new Error ( "Failed!" )
228+ ) ;
229+ expect ( loader . changeCount ) . toEqual ( 2 ) ;
230+ expect ( loader . current ) . toEqual ( "failure" ) ;
231+
232+ loader . next ( "FETCH" ) ;
233+ expect ( fetch ) . toHaveBeenCalledTimes ( 1 ) ;
234+ expect ( loader . changeCount ) . toEqual ( 2 ) ;
235+
236+ loader . next ( "RETRY" ) ;
237+ expect ( loader . current ) . toEqual ( "loading" ) ;
238+ expect ( loader . changeCount ) . toEqual ( 3 ) ;
239+
240+ expect ( fetch ) . toHaveBeenCalledTimes ( 2 ) ;
241+ expect ( fetch ) . toHaveBeenLastCalledWith ( "https://example.org/" ) ;
242+
243+ await expect ( loader . results ) . resolves . toEqual ( { fetchData : 42 } ) ;
244+ expect ( loader . changeCount ) . toEqual ( 4 ) ;
245+ expect ( loader . current ) . toEqual ( "success" ) ;
246+ } ) ;
247+ } ) ;
248+ } ) ;
249+
126250describe ( "Form Field Machine with always()" , ( ) => {
127251 const isValid = jest . fn ( ) ;
128252 beforeEach ( isValid . mockClear ) ;
@@ -294,6 +418,39 @@ describe("Switch", () => {
294418 } ) ;
295419} ) ;
296420
421+ describe ( "Switch with symbol messages" , ( ) => {
422+ const FLICK = Symbol ( 'FLICK' ) ;
423+
424+ function * Switch ( ) {
425+ function * OFF ( ) {
426+ yield on ( FLICK , ON ) ;
427+ }
428+ function * ON ( ) {
429+ yield on ( FLICK , OFF ) ;
430+ }
431+
432+ return OFF ;
433+ }
434+
435+ test ( "sending events" , ( ) => {
436+ const machine = start ( Switch ) ;
437+ expect ( machine ) . toBeDefined ( ) ;
438+ expect ( machine . current ) . toEqual ( "OFF" ) ;
439+
440+ machine . next ( FLICK ) ;
441+ expect ( machine . current ) . toEqual ( "ON" ) ;
442+ expect ( machine . changeCount ) . toEqual ( 1 ) ;
443+
444+ machine . next ( FLICK ) ;
445+ expect ( machine . current ) . toEqual ( "OFF" ) ;
446+ expect ( machine . changeCount ) . toEqual ( 2 ) ;
447+
448+ machine . next ( Symbol ( 'will be ignored' ) ) ;
449+ expect ( machine . current ) . toEqual ( "OFF" ) ;
450+ expect ( machine . changeCount ) . toEqual ( 2 ) ;
451+ } ) ;
452+ } ) ;
453+
297454/*describe("Counter", () => {
298455 function* Counter() {
299456 function* initial() {
0 commit comments