diff --git a/src/node/api.mjs b/src/node/api.mjs index 5733fb1d..1ac8e42b 100644 --- a/src/node/api.mjs +++ b/src/node/api.mjs @@ -191,7 +191,30 @@ export function _wrap(OpClass) { */ wrapped = async (input, args=null) => { const {transformedInput, transformedArgs} = prepareOp(opInstance, input, args); + + // SPECIAL CASE for Magic. + if (opInstance.flowControl) { + opInstance.ingValues = transformedArgs; + + const state = { + "progress": 0, + "dish": ensureIsDish(transformedInput), + "opList": [opInstance], + "numJumps": 0, + "numRegisters": 0, + "forkOffset": 0 + }; + + const updatedState = await opInstance.run(state); + + return new NodeDish({ + value: updatedState.dish.value, + type: opInstance.outputType, + }); + } + const result = await opInstance.run(transformedInput, transformedArgs); + return new NodeDish({ value: result, type: opInstance.outputType, diff --git a/tests/lib/TestRegister.mjs b/tests/lib/TestRegister.mjs index 0236fc9f..452f3f55 100644 --- a/tests/lib/TestRegister.mjs +++ b/tests/lib/TestRegister.mjs @@ -152,7 +152,7 @@ class TestRegister { result.status = "passing"; } catch (e) { result.status = "erroring"; - result.output = e.message; + result.output = `${e.message}\nError: ${e.stack}`; } testResults.push(result); diff --git a/tests/node/tests/operations.mjs b/tests/node/tests/operations.mjs index baf3f238..b85de4aa 100644 --- a/tests/node/tests/operations.mjs +++ b/tests/node/tests/operations.mjs @@ -1075,6 +1075,60 @@ ExifImageHeight: 57`); assert.equal(output, res.value); }), + it("performs MAGIC", async () => { + const input = "WUagwsiae6mP8gNtCCLUFpCpCB26RmBDoDD8PacdAmzAzBVjkK2QstFXaKhpC6iUS7RHqXrJtFisoRSgoJ4whjm1arm864qaNq4RcfUmLHrcsAaZc5TXCYifNdgS83gDeejGX46gaiMyuBV6EskHt1scgJ88x2tNSotQDwbGY1mmCob2ARGFvCKYNqiN9ipMq1ZU1mgkdbNuGcb76aRtYWhCGUc8g93UJudhb8htsheZnwTpgqhx83SVJSZXMXUjJT2zmpC7uXWtumqokbdSi88YtkWDAc1Toouh2oH4D4ddmNKJWUDpMwmngUmK14xwmomccPQE9hM172APnSqwxdKQ172RkcAsysnmj5gGtRmVNNh2s359wr6mS2QRP"; + const depth = 3; + + const res = await chef.magic(input, { + depth: 3 + }); + + // assert against the structure of the output, rather than the values. + assert.strictEqual(res.value.length, depth + 1); + res.value.forEach(row => { + assert.ok(row.recipe); + assert.ok(row.data); + assert.ok(row.languageScores); + assert.ok(Object.prototype.hasOwnProperty.call(row, "fileType")); // Can be null, so cannot just use ok + assert.ok(row.entropy); + assert.ok(row.matchingOps); + assert.ok(Object.prototype.hasOwnProperty.call(row, "useful")); + assert.ok(Object.prototype.hasOwnProperty.call(row, "matchesCrib")); + + row.recipe.forEach(item => { + assert.ok(Object.prototype.hasOwnProperty.call(item, "op"), `No 'op' property in item ${item}`); + assert.strictEqual(typeof item.op, "string"); + assert.ok(Object.prototype.hasOwnProperty.call(item, "args"), `No 'args' property in item ${item}`); + assert.ok(Array.isArray(item.args)); + }); + + row.languageScores.forEach(score => { + assert.ok(Object.prototype.hasOwnProperty.call(score, "lang"), `No 'lang' property in languageScore ${score}`); + assert.strictEqual(typeof score.lang, "string"); + assert.ok(Object.prototype.hasOwnProperty.call(score, "score"), `No 'score' property in languageScore ${score}`); + assert.strictEqual(typeof score.score, "number"); + assert.ok(Object.prototype.hasOwnProperty.call(score, "probability"), `No 'probability' property in languageScore ${score}`); + assert.strictEqual(typeof score.probability, "number"); + }); + + row.matchingOps.forEach(op => { + assert.ok(Object.prototype.hasOwnProperty.call(op, "op"), `No 'op' property in matchingOp ${JSON.stringify(op)}`); + assert.strictEqual(typeof op.op, "string"); + assert.ok(Object.prototype.hasOwnProperty.call(op, "pattern"), `No 'pattern' property in matchingOp ${JSON.stringify(op)}`); + assert.ok(op.pattern instanceof RegExp); + assert.ok(Object.prototype.hasOwnProperty.call(op, "args"), `No 'args' property in matchingOp ${JSON.stringify(op)}`); + assert.ok(Array.isArray(op.args)); + assert.ok(Object.prototype.hasOwnProperty.call(op, "useful"), `No 'useful' property in matchingOp ${JSON.stringify(op)}`); + assert.ifError(op.useful); // Expect this to be undefined + assert.ok(Object.prototype.hasOwnProperty.call(op, "entropyRange"), `No 'entropyRange' property in matchingOp ${JSON.stringify(op)}`); + assert.ifError(op.entropyRange); // Expect this to be undefined + assert.ok(Object.prototype.hasOwnProperty.call(op, "output"), `No 'output' property in matchingOp ${JSON.stringify(op)}`); + assert.ifError(op.output); // Expect this to be undefined + }); + }); + + }), + ]);