diff --git a/CHANGELOG.md b/CHANGELOG.md
index 2a7b895..03ade9a 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -17,6 +17,10 @@ See [Semver](http://semver.org/).
- 🐞 Backwards-compatible bug fixes
- 📦 Minor packaging changes
+## v5.2.1
+
+- 🐞 `.pass` and `.fail` regex now support multiple line outputs per task.
+
## v5.2.0
- 🐞 [BatchProcessOptions](https://batch-cluster.js.org/classes/batchclusteroptions.html)`.pass`
diff --git a/src/BatchCluster.spec.ts b/src/BatchCluster.spec.ts
index b7079bd..128d4fc 100644
--- a/src/BatchCluster.spec.ts
+++ b/src/BatchCluster.spec.ts
@@ -273,6 +273,28 @@ describe("BatchCluster", function() {
)
})
+ it("accepts single and multi-line responses", async () => {
+ setFailrate(0)
+ const expected: string[] = []
+ const results = await Promise.all(
+ times(15, idx => {
+ // Make a distribution of single, double, and triple line outputs:
+ const worlds = times(idx % 3, ea => "world " + ea)
+ expected.push(
+ [idx + " HELLO", ...worlds]
+ .join("\n")
+ .toUpperCase()
+ )
+ const cmd = ["upcase " + idx + " hello", ...worlds].join(
+ "
"
+ )
+ return bc.enqueueTask(new Task(cmd, parser))
+ })
+ )
+ expect(results).to.eql(expected)
+ return
+ })
+
it("rejects a command that results in FAIL", async function() {
const task = new Task("invalid command", parser)
let error: Error | undefined
diff --git a/src/BatchClusterOptions.ts b/src/BatchClusterOptions.ts
index 51605b8..7c45420 100644
--- a/src/BatchClusterOptions.ts
+++ b/src/BatchClusterOptions.ts
@@ -1,7 +1,7 @@
-import { BatchProcessOptions } from "./BatchProcessOptions"
import { ChildProcessFactory } from "./BatchCluster"
+import { BatchProcessOptions } from "./BatchProcessOptions"
import { InternalBatchProcessOptions } from "./InternalBatchProcessOptions"
-import { toS, blank } from "./String"
+import { blank, toS } from "./String"
/**
* These parameter values have somewhat sensible defaults, but can be
@@ -113,7 +113,7 @@ export type AllOpts = BatchClusterOptions &
function toRe(s: string | RegExp) {
return s instanceof RegExp
? s
- : new RegExp("^(?:(.*)(?:\\r?\\n))?" + s + "(?:\\r?\\n)?$")
+ : new RegExp("^(?:([\\s\\S]*?)(?:\\r?\\n))?" + s + "(?:\\r?\\n)?$")
}
export function verifyOptions(
diff --git a/src/test.ts b/src/test.ts
index 3a2546d..9a419de 100644
--- a/src/test.ts
+++ b/src/test.ts
@@ -35,7 +35,7 @@ const rng =
Math.random
async function onLine(line: string): Promise {
- // write(`# ${_p.pid} onLine(${line.trim()})`)
+ // write(`# ${_p.pid} onLine(${line.trim()}) (newline = ${_p.env.newline})`)
const r = rng()
if (r < failrate) {
if (_p.env.unluckyfail === "1") {
@@ -58,6 +58,9 @@ async function onLine(line: string): Promise {
const tokens = line.split(/\s+/)
const firstToken = tokens.shift()
+ // support multi-line outputs:
+ const postToken = tokens.join(" ").split("
").join(newline)
+
try {
switch (firstToken) {
case "flaky":
@@ -81,12 +84,12 @@ async function onLine(line: string): Promise {
break
case "upcase":
- write(tokens.join(" ").toUpperCase())
+ write(postToken.toUpperCase())
write("PASS")
break
case "downcase":
- write(tokens.join(" ").toLowerCase())
+ write(postToken.toLowerCase())
write("PASS")
break
@@ -115,7 +118,7 @@ async function onLine(line: string): Promise {
// debouncing:
write("PASS")
await delay(1)
- console.error("Error: " + tokens.join(" "))
+ console.error("Error: " + postToken)
break
default: