22
33import { stripVTControlCharacters } from 'node:util'
44import { processError } from '@vitest/utils/error'
5- import { expect , test , vi } from 'vitest'
5+ import { describe , expect , test , vi } from 'vitest'
66
77test ( 'MessageChannel and MessagePort are available' , ( ) => {
88 expect ( MessageChannel ) . toBeDefined ( )
@@ -22,7 +22,7 @@ test('fetch, Request, Response, and BroadcastChannel are available', () => {
2222 expect ( BroadcastChannel ) . toBeDefined ( )
2323} )
2424
25- test ( 'Fetch API accepts other APIs' , ( ) => {
25+ test ( 'Fetch API accepts other APIs' , async ( ) => {
2626 expect . soft ( ( ) => new Request ( 'http://localhost' , { signal : new AbortController ( ) . signal } ) ) . not . toThrowError ( )
2727 expect . soft ( ( ) => new Request ( 'http://localhost' , { method : 'POST' , body : new FormData ( ) } ) ) . not . toThrowError ( )
2828 expect . soft ( ( ) => new Request ( 'http://localhost' , { method : 'POST' , body : new Blob ( ) } ) ) . not . toThrowError ( )
@@ -40,6 +40,110 @@ test('Fetch API accepts other APIs', () => {
4040 expect . soft ( ( ) => new Request ( 'http://localhost' , { method : 'POST' , body : searchParams } ) ) . not . toThrowError ( )
4141} )
4242
43+ describe ( 'FormData' , ( ) => {
44+ test ( 'can pass down a simple form data' , async ( ) => {
45+ const formData = new FormData ( )
46+ formData . set ( 'hello' , 'world' )
47+
48+ await expect ( ( async ( ) => {
49+ const req = new Request ( 'http://localhost:3000/' , {
50+ method : 'POST' ,
51+ body : formData ,
52+ } )
53+ await req . formData ( )
54+ } ) ( ) ) . resolves . not . toThrowError ( )
55+ } )
56+
57+ test ( 'can pass down form data from a FORM element' , async ( ) => {
58+ const form = document . createElement ( 'form' )
59+ document . body . append ( form )
60+
61+ const hello = document . createElement ( 'input' )
62+ hello . value = 'world'
63+ hello . type = 'text'
64+ hello . name = 'hello'
65+ form . append ( hello )
66+
67+ const formData = new FormData ( form )
68+ expect ( [ ...formData . entries ( ) ] ) . toEqual ( [
69+ [ 'hello' , 'world' ] ,
70+ ] )
71+
72+ await expect ( ( async ( ) => {
73+ const req = new Request ( 'http://localhost:3000/' , {
74+ method : 'POST' ,
75+ body : formData ,
76+ } )
77+ await req . formData ( )
78+ } ) ( ) ) . resolves . not . toThrowError ( )
79+ } )
80+
81+ test ( 'can pass down form data from a FORM element with a submitter' , async ( ) => {
82+ const form = document . createElement ( 'form' )
83+ document . body . append ( form )
84+
85+ const hello = document . createElement ( 'input' )
86+ hello . value = 'world'
87+ hello . type = 'text'
88+ hello . name = 'hello'
89+ form . append ( hello )
90+
91+ const submitter = document . createElement ( 'button' )
92+ submitter . type = 'submit'
93+ submitter . name = 'include'
94+ submitter . value = 'submitter'
95+ form . append ( submitter )
96+
97+ const formData = new FormData ( form , submitter )
98+ expect ( [ ...formData . entries ( ) ] ) . toEqual ( [
99+ [ 'hello' , 'world' ] ,
100+ [ 'include' , 'submitter' ] ,
101+ ] )
102+
103+ await expect ( ( async ( ) => {
104+ const req = new Request ( 'http://localhost:3000/' , {
105+ method : 'POST' ,
106+ body : formData ,
107+ } )
108+ await req . formData ( )
109+ } ) ( ) ) . resolves . not . toThrowError ( )
110+ } )
111+
112+ // https://developer.mozilla.org/en-US/docs/Web/API/FormData/FormData#exceptions
113+ test ( 'cannot pass down form data from a FORM element with a non-sumbit sumbitter' , async ( ) => {
114+ const form = document . createElement ( 'form' )
115+ document . body . append ( form )
116+ const submitter = document . createElement ( 'button' )
117+ submitter . type = 'button'
118+ form . append ( submitter )
119+
120+ expect ( ( ) => new FormData ( form , submitter ) ) . toThrowError (
121+ new TypeError ( 'The specified element is not a submit button' ) ,
122+ )
123+ } )
124+
125+ test ( 'cannot pass down form data from a FORM element with a sumbitter from a wrong form' , async ( ) => {
126+ const form1 = document . createElement ( 'form' )
127+ const form2 = document . createElement ( 'form' )
128+ document . body . append ( form1 , form2 )
129+ const submitter = document . createElement ( 'button' )
130+ submitter . type = 'submit'
131+ form2 . append ( submitter )
132+
133+ try {
134+ // can't use toThrow here because DOMException is not an Error
135+ const _ = new FormData ( form1 , submitter )
136+ }
137+ catch ( error : any ) {
138+ const expectedError = new DOMException (
139+ 'The specified element is not owned by this form element' ,
140+ 'NotFoundError' ,
141+ )
142+ expect ( error ) . toEqual ( expectedError )
143+ }
144+ } )
145+ } )
146+
43147test ( 'DOM APIs accept AbortController' , ( ) => {
44148 const element = document . createElement ( 'div' )
45149 document . body . append ( element )
0 commit comments