'use strict'; const common = require('../common'); const tmpdir = require('../common/tmpdir'); const { ok, strictEqual, throws, } = require('node:assert'); const { openSync, closeSync, readFile, readSync, readFileSync, writeSync, stat, } = require('node:fs'); const { Utf8Stream } = require('node:fs'); const { join } = require('node:path'); const { isMainThread } = require('node:worker_threads'); tmpdir.refresh(); let fileCounter = 0; if (isMainThread) { process.umask(0o000); } function getTempFile() { return join(tmpdir.path, `fastutf8stream-${process.pid}-${Date.now()}-${fileCounter++}.log`); } { const dest = getTempFile(); const fd = openSync(dest, 'w'); let callCount = 0; const stream = new Utf8Stream({ fd, minLength: 0, sync: true, fs: { writeSync: common.mustCall((...args) => { if (callCount++ === 0) return 0; writeSync(...args); }, 3), } }); stream.on('ready', common.mustCall(() => { ok(stream.write('hello world\n')); ok(stream.write('something else\n')); stream.end(); stream.on('finish', common.mustCall(() => { readFile(dest, 'utf8', common.mustSucceed((data) => { strictEqual(data, 'hello world\nsomething else\n'); })); })); })); } { const dest = getTempFile(); const fd = openSync(dest, 'w'); let callCount = 0; const stream = new Utf8Stream({ fd, minLength: 100, sync: false, fs: { writeSync: common.mustCall((...args) => { if (callCount++ === 0) return 0; return writeSync(...args); }, 2), } }); stream.on('ready', common.mustCall(() => { ok(stream.write('hello world\n')); ok(stream.write('something else\n')); stream.flushSync(); stream.on('write', common.mustNotCall()); stream.end(); stream.on('finish', common.mustCall(() => { readFile(dest, 'utf8', common.mustSucceed((data) => { strictEqual(data, 'hello world\nsomething else\n'); })); })); })); } { const dest = getTempFile(); const fd = openSync(dest, 'w'); const stream = new Utf8Stream({ fd, minLength: 0, sync: true, fs: { writeSync: common.mustCall(writeSync, 2), } }); ok(stream.write('hello world\n')); ok(stream.write('something else\n')); stream.on('drain', common.mustCall(() => { const data = readFileSync(dest, 'utf8'); strictEqual(data, 'hello world\nsomething else\n'); })); } { const dest = getTempFile(); const fd = openSync(dest, 'w'); const stream = new Utf8Stream({ fd, minLength: 0, sync: true }); const buf = Buffer.alloc(1024).fill('x').toString(); // 1 KB let length = 0; // Reduce iterations to avoid test timeout for (let i = 0; i < 1024; i++) { length += buf.length; stream.write(buf); } stream.end(); stream.on('finish', common.mustCall(() => { stat(dest, common.mustSucceed((stat) => { strictEqual(stat.size, length); })); })); } { const dest = getTempFile(); const fd = openSync(dest, 'w'); const stream = new Utf8Stream({ fd, minLength: 0, sync: true }); let buf = Buffer.alloc((1024 * 16) - 2).fill('x'); // 16KB - 2B const length = buf.length + 4; buf = buf.toString() + '🌲'; // 16 KB + 4B emoji stream.write(buf); stream.end(); stream.on('finish', common.mustCall(() => { stat(dest, common.mustSucceed((stat) => { strictEqual(stat.size, length); const char = Buffer.alloc(4); const readFd = openSync(dest, 'r'); readSync(readFd, char, 0, 4, length - 4); closeSync(readFd); strictEqual(char.toString(), '🌲'); })); })); } { const dest = getTempFile(); const stream = new Utf8Stream({ dest, sync: true }); ok(stream.write('hello world\n')); ok(stream.write('something else\n')); stream.flushSync(); // If we get here without error, the test passes stream.end(); } throws(() => { new Utf8Stream({ dest: '/path/to/nowhere', sync: true }); }, /ENOENT|EACCES/); { const dest = getTempFile(); const fd = openSync(dest, 'w'); const stream = new Utf8Stream({ fd, sync: true }); ok(stream.write('hello world 👀\n')); ok(stream.write('another line 👀\n')); // Check internal buffer length (may not be available in Utf8Stream) // This is implementation-specific, so we just verify writes succeeded ok(true, 'writes completed successfully'); stream.end(); } { const dest = getTempFile(); const fd = openSync(dest, 'w'); const stream = new Utf8Stream({ fd, sync: true, minLength: 20 }); let str = ''; for (let i = 0; i < 20; i++) { ok(stream.write('👀')); str += '👀'; } // Check internal buffer length (implementation-specific) ok(true, 'writes completed successfully'); readFile(dest, 'utf8', common.mustSucceed((data) => { strictEqual(data, str); })); }