mirror of
https://github.com/gchq/CyberChef.git
synced 2025-04-20 06:55:08 -04:00
OperationErrors now bubble up to the top of the API.
Added test functionality for node api refactor TestRegister into class
This commit is contained in:
parent
e50758f0a6
commit
5fb50a1759
6 changed files with 194 additions and 30 deletions
1
.gitignore
vendored
1
.gitignore
vendored
|
@ -10,3 +10,4 @@ src/core/config/modules/*
|
||||||
src/core/config/OperationConfig.json
|
src/core/config/OperationConfig.json
|
||||||
src/core/operations/index.mjs
|
src/core/operations/index.mjs
|
||||||
|
|
||||||
|
**/*.DS_Store
|
|
@ -7,7 +7,6 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import Dish from "../core/Dish";
|
import Dish from "../core/Dish";
|
||||||
import log from "loglevel";
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Extract default arg value from operation argument
|
* Extract default arg value from operation argument
|
||||||
|
@ -33,13 +32,21 @@ export function wrap(Operation) {
|
||||||
/**
|
/**
|
||||||
* Wrapped operation run function
|
* Wrapped operation run function
|
||||||
*/
|
*/
|
||||||
return async (input, args=null) => {
|
return async (input, args=null, callback) => {
|
||||||
|
|
||||||
|
if (callback && typeof callback !== "function") {
|
||||||
|
throw TypeError("Expected callback to be a function");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!callback && typeof args === "function") {
|
||||||
|
callback = args;
|
||||||
|
args = null;
|
||||||
|
}
|
||||||
|
|
||||||
const operation = new Operation();
|
const operation = new Operation();
|
||||||
const dish = new Dish();
|
const dish = new Dish();
|
||||||
|
|
||||||
// Stolen from Recipe. Only works there as raw input is one
|
const type = Dish.typeEnum(input.constructor.name);
|
||||||
// of these types. consider a mapping for all use cases like below.
|
|
||||||
const type = input instanceof ArrayBuffer ? Dish.ARRAY_BUFFER : Dish.STRING;
|
|
||||||
dish.set(input, type);
|
dish.set(input, type);
|
||||||
|
|
||||||
if (!args) {
|
if (!args) {
|
||||||
|
@ -51,10 +58,22 @@ export function wrap(Operation) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
const transformedInput = await dish.get(operation.inputType);
|
const transformedInput = await dish.get(operation.inputType);
|
||||||
|
|
||||||
|
// Allow callback or promsise / async-await
|
||||||
|
if (callback) {
|
||||||
|
try {
|
||||||
|
const out = operation.run(transformedInput, args);
|
||||||
|
callback(null, out);
|
||||||
|
} catch (e) {
|
||||||
|
callback(e);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
return operation.run(transformedInput, args);
|
return operation.run(transformedInput, args);
|
||||||
|
}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* First draft
|
* First draft
|
||||||
* @param input
|
* @param input
|
||||||
|
|
|
@ -5,37 +5,49 @@
|
||||||
* ensure that they will get run by the frontend.
|
* ensure that they will get run by the frontend.
|
||||||
*
|
*
|
||||||
* @author tlwr [toby@toby.codes]
|
* @author tlwr [toby@toby.codes]
|
||||||
* @copyright Crown Copyright 2017
|
* @author d98762625 [d98762625@gmail.com]
|
||||||
|
* @copyright Crown Copyright 2018
|
||||||
* @license Apache-2.0
|
* @license Apache-2.0
|
||||||
*/
|
*/
|
||||||
import Chef from "../src/core/Chef";
|
import Chef from "../src/core/Chef";
|
||||||
|
|
||||||
(function() {
|
/**
|
||||||
/**
|
|
||||||
* Object to store and run the list of tests.
|
* Object to store and run the list of tests.
|
||||||
*
|
*
|
||||||
* @class
|
* @class
|
||||||
* @constructor
|
* @constructor
|
||||||
*/
|
*/
|
||||||
function TestRegister() {
|
class TestRegister {
|
||||||
this.tests = [];
|
|
||||||
}
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* initialise with no tests
|
||||||
|
*/
|
||||||
|
constructor() {
|
||||||
|
this.tests = [];
|
||||||
|
this.apiTests = [];
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Add a list of tests to the register.
|
* Add a list of tests to the register.
|
||||||
*
|
*
|
||||||
* @param {Object[]} tests
|
* @param {Object[]} tests
|
||||||
*/
|
*/
|
||||||
TestRegister.prototype.addTests = function(tests) {
|
addTests(tests) {
|
||||||
this.tests = this.tests.concat(tests);
|
this.tests = this.tests.concat(tests);
|
||||||
};
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Add a list of api tests to the register
|
||||||
|
* @param {Object[]} tests
|
||||||
|
*/
|
||||||
|
addApiTests(tests) {
|
||||||
|
this.apiTests = this.apiTests.concat(tests);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Runs all the tests in the register.
|
* Runs all the tests in the register.
|
||||||
*/
|
*/
|
||||||
TestRegister.prototype.runTests = function() {
|
runTests () {
|
||||||
return Promise.all(
|
return Promise.all(
|
||||||
this.tests.map(function(test, i) {
|
this.tests.map(function(test, i) {
|
||||||
const chef = new Chef();
|
const chef = new Chef();
|
||||||
|
@ -81,12 +93,29 @@ import Chef from "../src/core/Chef";
|
||||||
});
|
});
|
||||||
})
|
})
|
||||||
);
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Run all api related tests and wrap results in report format
|
||||||
|
*/
|
||||||
|
runApiTests() {
|
||||||
|
return Promise.all(this.apiTests.map(async function(test, i) {
|
||||||
|
const result = {
|
||||||
|
test: test,
|
||||||
|
status: null,
|
||||||
|
output: null,
|
||||||
};
|
};
|
||||||
|
try {
|
||||||
|
await test.run();
|
||||||
|
result.status = "passing";
|
||||||
|
} catch (e) {
|
||||||
|
result.status = "erroring";
|
||||||
|
result.output = e.message;
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Export an instance to make a singleton
|
||||||
// Singleton TestRegister, keeping things simple and obvious.
|
export default new TestRegister();
|
||||||
global.TestRegister = global.TestRegister || new TestRegister();
|
|
||||||
})();
|
|
||||||
|
|
||||||
export default global.TestRegister;
|
|
||||||
|
|
||||||
|
|
|
@ -55,6 +55,9 @@ import "./tests/operations/SymmetricDifference";
|
||||||
import "./tests/operations/CartesianProduct";
|
import "./tests/operations/CartesianProduct";
|
||||||
import "./tests/operations/PowerSet";
|
import "./tests/operations/PowerSet";
|
||||||
|
|
||||||
|
|
||||||
|
import "./tests/nodeApi/nodeApi";
|
||||||
|
|
||||||
let allTestsPassing = true;
|
let allTestsPassing = true;
|
||||||
const testStatusCounts = {
|
const testStatusCounts = {
|
||||||
total: 0,
|
total: 0,
|
||||||
|
@ -112,9 +115,12 @@ setTimeout(function() {
|
||||||
process.exit(1);
|
process.exit(1);
|
||||||
}, 10 * 1000);
|
}, 10 * 1000);
|
||||||
|
|
||||||
|
Promise.all([
|
||||||
TestRegister.runTests()
|
TestRegister.runTests(),
|
||||||
.then(function(results) {
|
TestRegister.runApiTests()
|
||||||
|
])
|
||||||
|
.then(function(resultsPair) {
|
||||||
|
const results = resultsPair[0].concat(resultsPair[1]);
|
||||||
results.forEach(handleTestResult);
|
results.forEach(handleTestResult);
|
||||||
|
|
||||||
console.log("\n");
|
console.log("\n");
|
||||||
|
@ -132,3 +138,4 @@ TestRegister.runTests()
|
||||||
|
|
||||||
process.exit(allTestsPassing ? 0 : 1);
|
process.exit(allTestsPassing ? 0 : 1);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
45
test/tests/assertionHandler.mjs
Normal file
45
test/tests/assertionHandler.mjs
Normal file
|
@ -0,0 +1,45 @@
|
||||||
|
/**
|
||||||
|
* assertionHandler.mjs
|
||||||
|
*
|
||||||
|
* Pair native node assertions with a description for
|
||||||
|
* the benefit of the TestRegister.
|
||||||
|
*
|
||||||
|
* @author d98762625 [d98762625@gmail.com]
|
||||||
|
* @copyright Crown Copyright 2018
|
||||||
|
* @license Apache-2.0
|
||||||
|
*/
|
||||||
|
|
||||||
|
import assert from "assert";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* it - wrapper for assertions to provide a helpful description
|
||||||
|
* to the TestRegister
|
||||||
|
* @param {String} description - The description of the test
|
||||||
|
* @param {Function} assertion - The test
|
||||||
|
*
|
||||||
|
* @example
|
||||||
|
* // One assertion
|
||||||
|
* it("should run one assertion", () => assert.equal(1,1))
|
||||||
|
*
|
||||||
|
* @example
|
||||||
|
* // multiple assertions
|
||||||
|
* it("should handle multiple assertions", () => {
|
||||||
|
* assert.equal(1,1)
|
||||||
|
* assert.notEqual(3,4)
|
||||||
|
* })
|
||||||
|
*
|
||||||
|
* @example
|
||||||
|
* // async assertions
|
||||||
|
* it("should handle async", async () => {
|
||||||
|
* let r = await asyncFunc()
|
||||||
|
* assert(r)
|
||||||
|
* })
|
||||||
|
*/
|
||||||
|
export function it(name, run) {
|
||||||
|
return {
|
||||||
|
name,
|
||||||
|
run
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
export default it;
|
63
test/tests/nodeApi/nodeApi.mjs
Normal file
63
test/tests/nodeApi/nodeApi.mjs
Normal file
|
@ -0,0 +1,63 @@
|
||||||
|
/* eslint no-console: 0 */
|
||||||
|
|
||||||
|
/**
|
||||||
|
* nodeApi.js
|
||||||
|
*
|
||||||
|
* Test node api utilities
|
||||||
|
*
|
||||||
|
* @author d98762625 [d98762625@gmail.com]
|
||||||
|
* @copyright Crown Copyright 2018
|
||||||
|
* @license Apache-2.0
|
||||||
|
*/
|
||||||
|
|
||||||
|
import assert from "assert";
|
||||||
|
import it from "../assertionHandler";
|
||||||
|
import chef from "../../../src/node/index";
|
||||||
|
import TestRegister from "../../TestRegister";
|
||||||
|
|
||||||
|
TestRegister.addApiTests([
|
||||||
|
it("should have some operations", () => {
|
||||||
|
assert(chef);
|
||||||
|
assert(chef.toBase32);
|
||||||
|
assert(chef.setUnion);
|
||||||
|
assert(!chef.randomFunction);
|
||||||
|
}),
|
||||||
|
|
||||||
|
it("should have an async/await api", async () => {
|
||||||
|
try {
|
||||||
|
const result = await chef.toBase32("input");
|
||||||
|
assert.notEqual("something", result);
|
||||||
|
} catch (e) {
|
||||||
|
// shouldnt reach here
|
||||||
|
assert(false);
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
const fail = chef.setUnion("1");
|
||||||
|
// shouldnt get here
|
||||||
|
assert(false);
|
||||||
|
} catch (e) {
|
||||||
|
assert(true);
|
||||||
|
}
|
||||||
|
}),
|
||||||
|
|
||||||
|
it("should have a callback API", async () => {
|
||||||
|
await chef.toBase32("something", (err, result) => {
|
||||||
|
if (err) {
|
||||||
|
assert(false);
|
||||||
|
} else {
|
||||||
|
assert.equal("ONXW2ZLUNBUW4ZY=", result);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}),
|
||||||
|
|
||||||
|
it("should handle errors in callback API", async () => {
|
||||||
|
await chef.setUnion("1", (err, result) => {
|
||||||
|
if (err) {
|
||||||
|
assert(true);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
assert(false);
|
||||||
|
});
|
||||||
|
})
|
||||||
|
]);
|
Loading…
Add table
Add a link
Reference in a new issue