@@ -151,6 +151,117 @@ describe('FileReader', function () {
151151 expect ( new TextDecoder ( ) . decode ( ab ) ) . toBe ( '42' ) ;
152152 } ) ;
153153
154+ // The FileReaderModule mock always resolves with these bytes, regardless of
155+ // the blob it is handed.
156+ const MOCK_READ_RESULT = [ 52 , 50 ] ;
157+
158+ it ( 'resolves result with the ArrayBuffer the native module returns' , async ( ) => {
159+ const reader = new FileReader ( ) ;
160+
161+ await new Promise < Event > ( resolve => {
162+ reader . onloadend = resolve ;
163+ reader . readAsArrayBuffer ( new Blob ( ) ) ;
164+ } ) ;
165+
166+ expect ( reader . readyState ) . toBe ( FileReader . DONE ) ;
167+ expect ( reader . result ) . toBeInstanceOf ( ArrayBuffer ) ;
168+ const result = reader . result ;
169+ if ( ! ( result instanceof ArrayBuffer ) ) {
170+ throw new Error ( 'expected ArrayBuffer' ) ;
171+ }
172+ expect ( Array . from ( new Uint8Array ( result ) ) ) . toEqual ( MOCK_READ_RESULT ) ;
173+ } ) ;
174+
175+ it ( 'throws a TypeError when readAsArrayBuffer is given null' , ( ) => {
176+ const reader = new FileReader ( ) ;
177+ expect ( ( ) => reader . readAsArrayBuffer ( null ) ) . toThrow ( TypeError ) ;
178+ expect ( reader . readyState ) . toBe ( FileReader . EMPTY ) ;
179+ } ) ;
180+
181+ it ( 'should abort a pending ArrayBuffer read without firing load' , async ( ) => {
182+ const reader = new FileReader ( ) ;
183+ let loaded = false ;
184+ reader . onload = ( ) => {
185+ loaded = true ;
186+ } ;
187+ reader . readAsArrayBuffer ( new Blob ( ) ) ;
188+ reader . abort ( ) ;
189+
190+ expect ( reader . readyState ) . toBe ( FileReader . DONE ) ;
191+ expect ( reader . result ) . toBe ( null ) ;
192+
193+ await Promise . resolve ( ) ;
194+ expect ( loaded ) . toBe ( false ) ;
195+ expect ( reader . result ) . toBe ( null ) ;
196+ } ) ;
197+
198+ it ( 'should discard a stale ArrayBuffer result when a newer read is current' , async ( ) => {
199+ const resolvers : Array < ( ArrayBuffer ) => void > = [ ] ;
200+ const spy = jest
201+ . spyOn ( FileReaderModuleMock , 'readAsArrayBuffer' )
202+ . mockImplementation (
203+ ( ) =>
204+ new Promise ( resolve => {
205+ resolvers . push ( resolve ) ;
206+ } ) ,
207+ ) ;
208+
209+ const reader = new FileReader ( ) ;
210+ let loaded = false ;
211+ reader . onload = ( ) => {
212+ loaded = true ;
213+ } ;
214+
215+ reader . readAsArrayBuffer ( new Blob ( ) ) ;
216+ reader . abort ( ) ;
217+ expect ( reader . result ) . toBe ( null ) ;
218+
219+ const done = new Promise < Event > ( resolve => {
220+ reader . onloadend = resolve ;
221+ } ) ;
222+ reader . readAsArrayBuffer ( new Blob ( ) ) ;
223+
224+ // Stale first read settles with different bytes; the readId guard must drop it.
225+ resolvers [ 0 ] ( Uint8Array . from ( [ 9 , 9 , 9 ] ) . buffer ) ;
226+ await Promise . resolve ( ) ;
227+ expect ( reader . readyState ) . toBe ( FileReader . LOADING ) ;
228+ expect ( reader . result ) . toBe ( null ) ;
229+ expect ( loaded ) . toBe ( false ) ;
230+
231+ resolvers [ 1 ] ( Uint8Array . from ( [ 52 , 50 ] ) . buffer ) ;
232+ await done ;
233+ expect ( reader . readyState ) . toBe ( FileReader . DONE ) ;
234+ expect ( reader . result ) . toBeInstanceOf ( ArrayBuffer ) ;
235+ const result = reader . result ;
236+ if ( ! ( result instanceof ArrayBuffer ) ) {
237+ throw new Error ( 'expected ArrayBuffer' ) ;
238+ }
239+ expect ( Array . from ( new Uint8Array ( result ) ) ) . toEqual ( [ 52 , 50 ] ) ;
240+ expect ( loaded ) . toBe ( true ) ;
241+
242+ spy . mockRestore ( ) ;
243+ } ) ;
244+
245+ it ( 'rejects a failed ArrayBuffer read with a NotReadableError DOMException' , async ( ) => {
246+ const spy = jest
247+ . spyOn ( FileReaderModuleMock , 'readAsArrayBuffer' )
248+ . mockRejectedValue ( new Error ( 'The specified blob is invalid' ) ) ;
249+
250+ const reader = new FileReader ( ) ;
251+ await new Promise < Event > ( resolve => {
252+ reader . onloadend = resolve ;
253+ reader . readAsArrayBuffer ( new Blob ( ) ) ;
254+ } ) ;
255+
256+ expect ( reader . readyState ) . toBe ( FileReader . DONE ) ;
257+ expect ( reader . result ) . toBe ( null ) ;
258+ expect ( reader . error ) . not . toBe ( null ) ;
259+ expect ( reader . error ?. message ) . toBe ( 'The specified blob is invalid' ) ;
260+ expect ( reader . error ?. name ) . toBe ( 'NotReadableError' ) ;
261+
262+ spy . mockRestore ( ) ;
263+ } ) ;
264+
154265 it ( 'fires lifecycle events in spec order for a successful read' , async ( ) => {
155266 const reader = new FileReader ( ) ;
156267 const events : Array < string > = [];
0 commit comments