11'use strict' ;
22
33const common = require ( '../common' ) ;
4- const fs = require ( 'fs' ) ;
5- const fsPromises = fs . promises ;
4+
5+ // This test ensures that filehandle.write accepts "named parameters" object
6+ // and doesn't interpret objects as strings
7+
8+ const assert = require ( 'assert' ) ;
9+ const fsPromises = require ( 'fs' ) . promises ;
610const path = require ( 'path' ) ;
711const tmpdir = require ( '../common/tmpdir' ) ;
8- const assert = require ( 'assert' ) ;
912
1013tmpdir . refresh ( ) ;
1114
1215const dest = path . resolve ( tmpdir . path , 'tmp.txt' ) ;
1316const buffer = Buffer . from ( 'zyx' ) ;
1417
15- ( async ( ) => {
16- let fh = await fsPromises . open ( dest , 'w+' ) ;
17-
18- assert . rejects ( async ( ) => {
19- await fh . write (
20- { }
21- ) ;
22- } , {
23- code : 'ERR_INVALID_ARG_TYPE' ,
24- name : 'TypeError' ,
25- message : 'The "buffer" argument must be an instance of Buffer, ' +
26- 'TypedArray, or DataView. Received undefined'
27- } ) ;
28- assert . rejects ( async ( ) => {
29- await fh . write (
30- { buffer : 'abc' }
31- ) ;
32- } , {
33- code : 'ERR_INVALID_ARG_TYPE' ,
34- name : 'TypeError' ,
35- message : 'The "buffer" argument must be an instance of Buffer, ' +
36- 'TypedArray, or DataView. Received type string (\'abc\')'
37- } ) ;
38- assert . rejects ( async ( ) => {
39- await fh . write (
40- { buffer, length : 5 }
41- ) ;
42- } , {
43- code : 'ERR_OUT_OF_RANGE' ,
44- name : 'RangeError' ,
45- message : 'The value of "length" is out of range. ' +
46- 'It must be <= 3. Received 5'
47- } ) ;
48- assert . rejects ( async ( ) => {
49- await fh . write (
50- { buffer, offset : 5 }
51- ) ;
52- } , {
53- code : 'ERR_OUT_OF_RANGE' ,
54- name : 'RangeError' ,
55- message : 'The value of "offset" is out of range. ' +
56- 'It must be <= 3. Received 5'
57- } ) ;
58- assert . rejects ( async ( ) => {
59- await fh . write (
60- { buffer, offset : 1 }
61- ) ;
62- } , {
63- code : 'ERR_OUT_OF_RANGE' ,
64- name : 'RangeError' ,
65- message : 'The value of "length" is out of range. ' +
66- 'It must be <= 2. Received 3'
67- } ) ;
68- assert . rejects ( async ( ) => {
69- await fh . write (
70- { buffer, length : 1 , offset : 3 }
71- ) ;
72- } , {
73- code : 'ERR_OUT_OF_RANGE' ,
74- name : 'RangeError' ,
75- message : 'The value of "length" is out of range. ' +
76- 'It must be <= 0. Received 1'
77- } ) ;
78- assert . rejects ( async ( ) => {
79- await fh . write (
80- { buffer, length : - 1 }
81- ) ;
82- } , {
83- code : 'ERR_OUT_OF_RANGE' ,
84- name : 'RangeError' ,
85- message : 'The value of "length" is out of range. ' +
86- 'It must be >= 0. Received -1'
87- } ) ;
88- assert . rejects ( async ( ) => {
89- await fh . write (
90- { buffer, offset : - 1 }
91- ) ;
92- } , {
93- code : 'ERR_OUT_OF_RANGE' ,
94- name : 'RangeError' ,
95- message : 'The value of "offset" is out of range. ' +
96- 'It must be >= 0 && <= 9007199254740991. Received -1'
97- } ) ;
98-
99- await fh . close ( ) ;
18+ async function testInvalid ( dest , expectedCode , params ) {
19+ let fh ;
20+ try {
21+ fh = await fsPromises . open ( dest , 'w+' ) ;
22+ await assert . rejects (
23+ async ( ) => fh . write ( params ) ,
24+ { code : expectedCode } ) ;
25+ } finally {
26+ await fh ?. close ( ) ;
27+ }
28+ }
10029
101- for ( const params of [
102- { buffer } ,
103- { buffer, length : 1 } ,
104- { buffer, position : 5 } ,
105- { buffer, length : 1 , position : 5 } ,
106- { buffer, length : 1 , position : - 1 , offset : 2 } ,
107- { buffer, length : null } ,
108- ] ) {
30+ async function testValid ( dest , params ) {
31+ let fh ;
32+ try {
10933 fh = await fsPromises . open ( dest , 'w+' ) ;
11034 const writeResult = await fh . write ( params ) ;
11135 const writeBufCopy = Uint8Array . prototype . slice . call ( writeResult . buffer ) ;
11236 const readResult = await fh . read ( params ) ;
11337 const readBufCopy = Uint8Array . prototype . slice . call ( readResult . buffer ) ;
11438
115- // Test compatibility with filehandle.read counterpart with reused params
11639 assert . ok ( writeResult . bytesWritten >= readResult . bytesRead ) ;
11740 if ( params . length !== undefined && params . length !== null ) {
11841 assert . strictEqual ( writeResult . bytesWritten , params . length ) ;
@@ -121,6 +44,44 @@ const buffer = Buffer.from('zyx');
12144 assert . deepStrictEqual ( writeBufCopy , readBufCopy ) ;
12245 }
12346 assert . deepStrictEqual ( writeResult . buffer , readResult . buffer ) ;
124- await fh . close ( ) ;
47+ } finally {
48+ await fh ?. close ( ) ;
49+ }
50+ }
51+
52+ ( async ( ) => {
53+ // Test if first argument is not wrongly interpreted as ArrayBufferView|string
54+ for ( const badParams of [
55+ undefined , null , true , 42 , 42n , Symbol ( '42' ) , NaN , [ ] ,
56+ { } ,
57+ { buffer : 'amNotParam' } ,
58+ { string : 'amNotParam' } ,
59+ { buffer : new Uint8Array ( 1 ) . buffer } ,
60+ new Date ( ) ,
61+ new String ( 'notPrimitive' ) ,
62+ { toString ( ) { return 'amObject' ; } } ,
63+ { [ Symbol . toPrimitive ] : ( hint ) => 'amObject' } ,
64+ ] ) {
65+ await testInvalid ( dest , 'ERR_INVALID_ARG_TYPE' , badParams ) ;
66+ }
67+
68+ // Various invalid params
69+ await testInvalid ( dest , 'ERR_OUT_OF_RANGE' , { buffer, length : 5 } ) ;
70+ await testInvalid ( dest , 'ERR_OUT_OF_RANGE' , { buffer, offset : 5 } ) ;
71+ await testInvalid ( dest , 'ERR_OUT_OF_RANGE' , { buffer, offset : 1 } ) ;
72+ await testInvalid ( dest , 'ERR_OUT_OF_RANGE' , { buffer, length : 1 , offset : 3 } ) ;
73+ await testInvalid ( dest , 'ERR_OUT_OF_RANGE' , { buffer, length : - 1 } ) ;
74+ await testInvalid ( dest , 'ERR_OUT_OF_RANGE' , { buffer, offset : - 1 } ) ;
75+
76+ // Test compatibility with filehandle.read counterpart with reused params
77+ for ( const params of [
78+ { buffer } ,
79+ { buffer, length : 1 } ,
80+ { buffer, position : 5 } ,
81+ { buffer, length : 1 , position : 5 } ,
82+ { buffer, length : 1 , position : - 1 , offset : 2 } ,
83+ { buffer, length : null } ,
84+ ] ) {
85+ await testValid ( dest , params ) ;
12586 }
12687} ) ( ) . then ( common . mustCall ( ) ) ;
0 commit comments