From a24982a733fdaa81564b032996f50e7ea6d2b10c Mon Sep 17 00:00:00 2001
From: Tim van der Meij <timvandermeij@gmail.com>
Date: Sat, 18 Dec 2021 15:52:04 +0100
Subject: [PATCH 1/2] Drop custom confirmation logic in favor of using the
 built-in Node.js `readline` module

Most likely this code predates our use of Node.js, but in Node.js asking
for user confirmation is a solved problem, so we can remove the custom
logic we have for this, which overall makes things much simpler.
---
 test/test.js      | 19 ++++++++----
 test/testutils.js | 77 -----------------------------------------------
 2 files changed, 13 insertions(+), 83 deletions(-)

diff --git a/test/test.js b/test/test.js
index 17e7b8bcb..3ec9f518d 100644
--- a/test/test.js
+++ b/test/test.js
@@ -25,6 +25,7 @@ var puppeteer = require("puppeteer");
 var url = require("url");
 var testUtils = require("./testutils.js");
 const dns = require("dns");
+const readline = require("readline");
 const yargs = require("yargs");
 
 // Chrome uses host `127.0.0.1` in the browser's websocket endpoint URL while
@@ -229,14 +230,17 @@ function updateRefImages() {
     sync(false); // don't remove tmp/ for botio
     return;
   }
-  testUtils.confirm(
+
+  const reader = readline.createInterface(process.stdin, process.stdout);
+  reader.question(
     "Would you like to update the master copy in ref/? [yn] ",
-    function (confirmed) {
-      if (confirmed) {
+    function (answer) {
+      if (answer.toLowerCase() === "y") {
         sync(true);
       } else {
         console.log("  OK, not updating.");
       }
+      reader.close();
     }
   );
 }
@@ -358,13 +362,16 @@ function startRefTest(masterMode, showRefImages) {
       }
       console.log("Temporary snapshot dir tmp/ is still around.");
       console.log("tmp/ can be removed if it has nothing you need.");
-      testUtils.confirm(
+
+      const reader = readline.createInterface(process.stdin, process.stdout);
+      reader.question(
         "SHOULD THIS SCRIPT REMOVE tmp/? THINK CAREFULLY [yn] ",
-        function (confirmed) {
-          if (confirmed) {
+        function (answer) {
+          if (answer.toLowerCase() === "y") {
             testUtils.removeDirSync(refsTmpDir);
           }
           setup();
+          reader.close();
         }
       );
     } else {
diff --git a/test/testutils.js b/test/testutils.js
index f4e7eb03d..e2cd76520 100644
--- a/test/testutils.js
+++ b/test/testutils.js
@@ -63,80 +63,3 @@ exports.ensureDirSync = function ensureDirSync(dir) {
     i++;
   }
 };
-
-var stdinBuffer = "",
-  endOfStdin = false,
-  stdinInitialized = false;
-var stdinOnLineCallbacks = [];
-
-function handleStdinBuffer() {
-  var callback;
-  if (endOfStdin) {
-    if (stdinBuffer && stdinOnLineCallbacks.length > 0) {
-      callback = stdinOnLineCallbacks.shift();
-      callback(stdinBuffer);
-      stdinBuffer = null;
-    }
-    while (stdinOnLineCallbacks.length > 0) {
-      callback = stdinOnLineCallbacks.shift();
-      callback();
-    }
-    return;
-  }
-  while (stdinOnLineCallbacks.length > 0) {
-    var i = stdinBuffer.indexOf("\n");
-    if (i < 0) {
-      return;
-    }
-    callback = stdinOnLineCallbacks.shift();
-    var result = stdinBuffer.substring(0, i + 1);
-    stdinBuffer = stdinBuffer.substring(i + 1);
-    callback(result);
-  }
-  // all callbacks handled, stop stdin processing
-  process.stdin.pause();
-}
-
-function initStdin() {
-  process.stdin.setEncoding("utf8");
-
-  process.stdin.on("data", function (chunk) {
-    stdinBuffer += chunk;
-    handleStdinBuffer();
-  });
-
-  process.stdin.on("end", function () {
-    endOfStdin = true;
-    handleStdinBuffer();
-  });
-}
-
-exports.prompt = function prompt(message, callback) {
-  if (!stdinInitialized) {
-    process.stdin.resume();
-    initStdin();
-    stdinInitialized = true;
-  } else if (stdinOnLineCallbacks.length === 0) {
-    process.stdin.resume();
-  }
-
-  process.stdout.write(message);
-  stdinOnLineCallbacks.push(callback);
-  handleStdinBuffer();
-};
-
-exports.confirm = function confirm(message, callback) {
-  exports.prompt(message, function (answer) {
-    if (answer === undefined) {
-      callback();
-      return;
-    }
-    if (answer[0].toLowerCase() === "y") {
-      callback(true);
-    } else if (answer[0].toLowerCase() === "n") {
-      callback(false);
-    } else {
-      confirm(message, callback);
-    }
-  });
-};

From 71326c6a1c23e4ebf1c477e1b595cd5869036e51 Mon Sep 17 00:00:00 2001
From: Tim van der Meij <timvandermeij@gmail.com>
Date: Sat, 18 Dec 2021 15:58:47 +0100
Subject: [PATCH 2/2] Enable the `no-var` linting rule in `test/testutils.js`

This is done automatically with the `gulp lint --fix` command with the
only exception of the `parts` variable.
---
 test/testutils.js | 19 +++++++++----------
 1 file changed, 9 insertions(+), 10 deletions(-)

diff --git a/test/testutils.js b/test/testutils.js
index e2cd76520..a67472606 100644
--- a/test/testutils.js
+++ b/test/testutils.js
@@ -13,13 +13,12 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-/* eslint-disable no-var */
 
 "use strict";
 
-var fs = require("fs");
-var path = require("path");
-var rimrafSync = require("rimraf").sync;
+const fs = require("fs");
+const path = require("path");
+const rimrafSync = require("rimraf").sync;
 
 exports.removeDirSync = function removeDirSync(dir) {
   fs.readdirSync(dir); // Will throw if dir is not a directory
@@ -29,14 +28,14 @@ exports.removeDirSync = function removeDirSync(dir) {
 };
 
 exports.copySubtreeSync = function copySubtreeSync(src, dest) {
-  var files = fs.readdirSync(src);
+  const files = fs.readdirSync(src);
   if (!fs.existsSync(dest)) {
     fs.mkdirSync(dest);
   }
   files.forEach(function (filename) {
-    var srcFile = path.join(src, filename);
-    var file = path.join(dest, filename);
-    var stats = fs.statSync(srcFile);
+    const srcFile = path.join(src, filename);
+    const file = path.join(dest, filename);
+    const stats = fs.statSync(srcFile);
     if (stats.isDirectory()) {
       copySubtreeSync(srcFile, file);
     } else {
@@ -49,8 +48,8 @@ exports.ensureDirSync = function ensureDirSync(dir) {
   if (fs.existsSync(dir)) {
     return;
   }
-  var parts = dir.split(path.sep),
-    i = parts.length;
+  const parts = dir.split(path.sep);
+  let i = parts.length;
   while (i > 1 && !fs.existsSync(parts.slice(0, i - 1).join(path.sep))) {
     i--;
   }