1+ 'use strict' ;
2+
3+ const common = require ( '../common' ) ;
4+
5+ // Test for FileHandle class accessibility and isFileHandle method
6+ // This validates the implementation of GitHub issue #61637
7+
8+ const fs = require ( 'fs' ) ;
9+ const fsPromises = require ( 'fs/promises' ) ;
10+ const path = require ( 'path' ) ;
11+ const assert = require ( 'assert' ) ;
12+ const tmpdir = require ( '../common/tmpdir' ) ;
13+ const tmpDir = tmpdir . path ;
14+
15+ tmpdir . refresh ( ) ;
16+
17+ async function testFileHandleAccessibility ( ) {
18+ // Test 1: FileHandle should be accessible from fs.FileHandle
19+ assert ( fs . FileHandle !== undefined , 'fs.FileHandle should be defined' ) ;
20+ assert ( typeof fs . FileHandle === 'function' , 'fs.FileHandle should be a function/class' ) ;
21+
22+ // Test 2: FileHandle should be accessible from fs.promises.FileHandle
23+ assert ( fsPromises . FileHandle !== undefined , 'fs.promises.FileHandle should be defined' ) ;
24+ assert ( typeof fsPromises . FileHandle === 'function' , 'fs.promises.FileHandle should be a function/class' ) ;
25+
26+ // Test 3: Both references should point to the same class
27+ assert . strictEqual ( fs . FileHandle , fsPromises . FileHandle , 'fs.FileHandle and fs.promises.FileHandle should be the same' ) ;
28+ }
29+
30+ async function testIsFileHandleMethod ( ) {
31+ // Test 4: FileHandle.isFileHandle should exist
32+ assert ( typeof fs . FileHandle . isFileHandle === 'function' , 'FileHandle.isFileHandle should be a function' ) ;
33+
34+ // Test 5: Test isFileHandle with actual FileHandle instance
35+ const testFilePath = path . join ( tmpDir , 'test_filehandle.txt' ) ;
36+ await fsPromises . writeFile ( testFilePath , 'test content' ) ;
37+
38+ const fileHandle = await fsPromises . open ( testFilePath , 'r' ) ;
39+ try {
40+ assert ( fs . FileHandle . isFileHandle ( fileHandle ) === true , 'isFileHandle should return true for FileHandle instance' ) ;
41+ } finally {
42+ await fileHandle . close ( ) ;
43+ }
44+
45+ // Test 6: Test instanceof check
46+ const fileHandle2 = await fsPromises . open ( testFilePath , 'r' ) ;
47+ try {
48+ assert ( fileHandle2 instanceof fs . FileHandle , 'fileHandle should be instance of FileHandle' ) ;
49+ assert ( fileHandle2 instanceof fsPromises . FileHandle , 'fileHandle should be instance of fs.promises.FileHandle' ) ;
50+ } finally {
51+ await fileHandle2 . close ( ) ;
52+ }
53+
54+ // Test 7: Test isFileHandle with non-FileHandle objects
55+ assert ( fs . FileHandle . isFileHandle ( { } ) === false , 'isFileHandle should return false for plain object' ) ;
56+ assert ( fs . FileHandle . isFileHandle ( null ) === false , 'isFileHandle should return false for null' ) ;
57+ assert ( fs . FileHandle . isFileHandle ( undefined ) === false , 'isFileHandle should return false for undefined' ) ;
58+ assert ( fs . FileHandle . isFileHandle ( 5 ) === false , 'isFileHandle should return false for number (fd)' ) ;
59+ assert ( fs . FileHandle . isFileHandle ( 'path/to/file' ) === false , 'isFileHandle should return false for string' ) ;
60+ assert ( fs . FileHandle . isFileHandle ( Buffer . from ( 'test' ) ) === false , 'isFileHandle should return false for Buffer' ) ;
61+
62+ // Clean up
63+ await fsPromises . unlink ( testFilePath ) ;
64+ }
65+
66+ async function testFileHandleUsage ( ) {
67+ // Test 8: Demonstrate practical usage - function accepting multiple input types
68+ const testFilePath = path . join ( tmpDir , 'test_usage.txt' ) ;
69+ await fsPromises . writeFile ( testFilePath , 'Hello FileHandle!' ) ;
70+
71+ async function flexibleReadFile ( input ) {
72+ if ( fs . FileHandle . isFileHandle ( input ) ) {
73+ // Input is already a FileHandle
74+ return await input . readFile ( { encoding : 'utf8' } ) ;
75+ } else if ( typeof input === 'string' ) {
76+ // Input is a file path
77+ const fh = await fsPromises . open ( input , 'r' ) ;
78+ try {
79+ return await fh . readFile ( { encoding : 'utf8' } ) ;
80+ } finally {
81+ await fh . close ( ) ;
82+ }
83+ } else {
84+ throw new TypeError ( 'Input must be a file path or FileHandle' ) ;
85+ }
86+ }
87+
88+ // Test with file path
89+ const content1 = await flexibleReadFile ( testFilePath ) ;
90+ assert . strictEqual ( content1 , 'Hello FileHandle!' ) ;
91+
92+ // Test with FileHandle
93+ const fh = await fsPromises . open ( testFilePath , 'r' ) ;
94+ try {
95+ const content2 = await flexibleReadFile ( fh ) ;
96+ assert . strictEqual ( content2 , 'Hello FileHandle!' ) ;
97+ } finally {
98+ await fh . close ( ) ;
99+ }
100+
101+ // Clean up
102+ await fsPromises . unlink ( testFilePath ) ;
103+ }
104+
105+ ( async ( ) => {
106+ await testFileHandleAccessibility ( ) ;
107+ await testIsFileHandleMethod ( ) ;
108+ await testFileHandleUsage ( ) ;
109+ } ) ( ) . then ( common . mustCall ( ) ) ;
0 commit comments