11cb0ef41Sopenharmony_ci'use strict'; 21cb0ef41Sopenharmony_ciconst common = require('../common'); 31cb0ef41Sopenharmony_ci 41cb0ef41Sopenharmony_ciif (common.isIBMi) 51cb0ef41Sopenharmony_ci common.skip('IBMi does not support `fs.watch()`'); 61cb0ef41Sopenharmony_ci 71cb0ef41Sopenharmony_ciconst { watch } = require('fs/promises'); 81cb0ef41Sopenharmony_ciconst fs = require('fs'); 91cb0ef41Sopenharmony_ciconst assert = require('assert'); 101cb0ef41Sopenharmony_ciconst { join } = require('path'); 111cb0ef41Sopenharmony_ciconst tmpdir = require('../common/tmpdir'); 121cb0ef41Sopenharmony_ci 131cb0ef41Sopenharmony_ciclass WatchTestCase { 141cb0ef41Sopenharmony_ci constructor(shouldInclude, dirName, fileName, field) { 151cb0ef41Sopenharmony_ci this.dirName = dirName; 161cb0ef41Sopenharmony_ci this.fileName = fileName; 171cb0ef41Sopenharmony_ci this.field = field; 181cb0ef41Sopenharmony_ci this.shouldSkip = !shouldInclude; 191cb0ef41Sopenharmony_ci } 201cb0ef41Sopenharmony_ci get dirPath() { return join(tmpdir.path, this.dirName); } 211cb0ef41Sopenharmony_ci get filePath() { return join(this.dirPath, this.fileName); } 221cb0ef41Sopenharmony_ci} 231cb0ef41Sopenharmony_ci 241cb0ef41Sopenharmony_ciconst kCases = [ 251cb0ef41Sopenharmony_ci // Watch on a directory should callback with a filename on supported systems 261cb0ef41Sopenharmony_ci new WatchTestCase( 271cb0ef41Sopenharmony_ci common.isLinux || common.isOSX || common.isWindows || common.isAIX, 281cb0ef41Sopenharmony_ci 'watch1', 291cb0ef41Sopenharmony_ci 'foo', 301cb0ef41Sopenharmony_ci 'filePath' 311cb0ef41Sopenharmony_ci ), 321cb0ef41Sopenharmony_ci // Watch on a file should callback with a filename on supported systems 331cb0ef41Sopenharmony_ci new WatchTestCase( 341cb0ef41Sopenharmony_ci common.isLinux || common.isOSX || common.isWindows, 351cb0ef41Sopenharmony_ci 'watch2', 361cb0ef41Sopenharmony_ci 'bar', 371cb0ef41Sopenharmony_ci 'dirPath' 381cb0ef41Sopenharmony_ci ), 391cb0ef41Sopenharmony_ci]; 401cb0ef41Sopenharmony_ci 411cb0ef41Sopenharmony_citmpdir.refresh(); 421cb0ef41Sopenharmony_ci 431cb0ef41Sopenharmony_cifor (const testCase of kCases) { 441cb0ef41Sopenharmony_ci if (testCase.shouldSkip) continue; 451cb0ef41Sopenharmony_ci fs.mkdirSync(testCase.dirPath); 461cb0ef41Sopenharmony_ci // Long content so it's actually flushed. 471cb0ef41Sopenharmony_ci const content1 = Date.now() + testCase.fileName.toLowerCase().repeat(1e4); 481cb0ef41Sopenharmony_ci fs.writeFileSync(testCase.filePath, content1); 491cb0ef41Sopenharmony_ci 501cb0ef41Sopenharmony_ci let interval; 511cb0ef41Sopenharmony_ci async function test() { 521cb0ef41Sopenharmony_ci const watcher = watch(testCase[testCase.field]); 531cb0ef41Sopenharmony_ci for await (const { eventType, filename } of watcher) { 541cb0ef41Sopenharmony_ci clearInterval(interval); 551cb0ef41Sopenharmony_ci assert.strictEqual(['rename', 'change'].includes(eventType), true); 561cb0ef41Sopenharmony_ci assert.strictEqual(filename, testCase.fileName); 571cb0ef41Sopenharmony_ci break; 581cb0ef41Sopenharmony_ci } 591cb0ef41Sopenharmony_ci 601cb0ef41Sopenharmony_ci // Waiting on it again is a non-op 611cb0ef41Sopenharmony_ci // eslint-disable-next-line no-unused-vars 621cb0ef41Sopenharmony_ci for await (const p of watcher) { 631cb0ef41Sopenharmony_ci assert.fail('should not run'); 641cb0ef41Sopenharmony_ci } 651cb0ef41Sopenharmony_ci } 661cb0ef41Sopenharmony_ci 671cb0ef41Sopenharmony_ci // Long content so it's actually flushed. toUpperCase so there's real change. 681cb0ef41Sopenharmony_ci const content2 = Date.now() + testCase.fileName.toUpperCase().repeat(1e4); 691cb0ef41Sopenharmony_ci interval = setInterval(() => { 701cb0ef41Sopenharmony_ci fs.writeFileSync(testCase.filePath, ''); 711cb0ef41Sopenharmony_ci fs.writeFileSync(testCase.filePath, content2); 721cb0ef41Sopenharmony_ci }, 100); 731cb0ef41Sopenharmony_ci 741cb0ef41Sopenharmony_ci test().then(common.mustCall()); 751cb0ef41Sopenharmony_ci} 761cb0ef41Sopenharmony_ci 771cb0ef41Sopenharmony_ciassert.rejects( 781cb0ef41Sopenharmony_ci async () => { 791cb0ef41Sopenharmony_ci // eslint-disable-next-line no-unused-vars, no-empty 801cb0ef41Sopenharmony_ci for await (const _ of watch(1)) { } 811cb0ef41Sopenharmony_ci }, 821cb0ef41Sopenharmony_ci { code: 'ERR_INVALID_ARG_TYPE' }); 831cb0ef41Sopenharmony_ci 841cb0ef41Sopenharmony_ciassert.rejects( 851cb0ef41Sopenharmony_ci async () => { 861cb0ef41Sopenharmony_ci // eslint-disable-next-line no-unused-vars, no-empty 871cb0ef41Sopenharmony_ci for await (const _ of watch(__filename, 1)) { } 881cb0ef41Sopenharmony_ci }, 891cb0ef41Sopenharmony_ci { code: 'ERR_INVALID_ARG_TYPE' }); 901cb0ef41Sopenharmony_ci 911cb0ef41Sopenharmony_ciassert.rejects( 921cb0ef41Sopenharmony_ci async () => { 931cb0ef41Sopenharmony_ci // eslint-disable-next-line no-unused-vars, no-empty 941cb0ef41Sopenharmony_ci for await (const _ of watch('', { persistent: 1 })) { } 951cb0ef41Sopenharmony_ci }, 961cb0ef41Sopenharmony_ci { code: 'ERR_INVALID_ARG_TYPE' }); 971cb0ef41Sopenharmony_ci 981cb0ef41Sopenharmony_ciassert.rejects( 991cb0ef41Sopenharmony_ci async () => { 1001cb0ef41Sopenharmony_ci // eslint-disable-next-line no-unused-vars, no-empty 1011cb0ef41Sopenharmony_ci for await (const _ of watch('', { recursive: 1 })) { } 1021cb0ef41Sopenharmony_ci }, 1031cb0ef41Sopenharmony_ci { code: 'ERR_INVALID_ARG_TYPE' }); 1041cb0ef41Sopenharmony_ci 1051cb0ef41Sopenharmony_ciassert.rejects( 1061cb0ef41Sopenharmony_ci async () => { 1071cb0ef41Sopenharmony_ci // eslint-disable-next-line no-unused-vars, no-empty 1081cb0ef41Sopenharmony_ci for await (const _ of watch('', { encoding: 1 })) { } 1091cb0ef41Sopenharmony_ci }, 1101cb0ef41Sopenharmony_ci { code: 'ERR_INVALID_ARG_VALUE' }); 1111cb0ef41Sopenharmony_ci 1121cb0ef41Sopenharmony_ciassert.rejects( 1131cb0ef41Sopenharmony_ci async () => { 1141cb0ef41Sopenharmony_ci // eslint-disable-next-line no-unused-vars, no-empty 1151cb0ef41Sopenharmony_ci for await (const _ of watch('', { signal: 1 })) { } 1161cb0ef41Sopenharmony_ci }, 1171cb0ef41Sopenharmony_ci { code: 'ERR_INVALID_ARG_TYPE' }); 1181cb0ef41Sopenharmony_ci 1191cb0ef41Sopenharmony_ci(async () => { 1201cb0ef41Sopenharmony_ci const ac = new AbortController(); 1211cb0ef41Sopenharmony_ci const { signal } = ac; 1221cb0ef41Sopenharmony_ci setImmediate(() => ac.abort()); 1231cb0ef41Sopenharmony_ci try { 1241cb0ef41Sopenharmony_ci // eslint-disable-next-line no-unused-vars, no-empty 1251cb0ef41Sopenharmony_ci for await (const _ of watch(__filename, { signal })) { } 1261cb0ef41Sopenharmony_ci } catch (err) { 1271cb0ef41Sopenharmony_ci assert.strictEqual(err.name, 'AbortError'); 1281cb0ef41Sopenharmony_ci } 1291cb0ef41Sopenharmony_ci})().then(common.mustCall()); 130