Make optional args in operation call use named properties rather than array

This commit is contained in:
d98762625 2018-05-11 19:25:14 +01:00
parent 7e8f78acaa
commit 0a0316a000
3 changed files with 65 additions and 11 deletions

View File

@ -20,10 +20,41 @@ function extractArg(arg) {
return arg.value;
}
/**
* transformArgs
*
* Take the default args array and update with any user-defined
* operation arguments. Allows user to define argyments in object style,
* with accommodation name matching. Using named args in the API is more
* clear to the user.
*
* Argument name matching is case and space insensitive
* @private
* @param {Object[]} originalArgs
* @param {Object} newArgs
*/
function transformArgs(originalArgs, newArgs) {
const allArgs = Object.assign([], originalArgs);
if (newArgs) {
Object.keys(newArgs).map((key) => {
const index = allArgs.findIndex((arg) => {
return arg.name.toLowerCase().replace(/ /g, "") ===
key.toLowerCase().replace(/ /g, "");
});
if (index > -1) {
allArgs[index].value = newArgs[key];
}
});
}
return allArgs.map(extractArg);
}
/**
* Wrap an operation to be consumed by node API.
* new Operation().run() becomes operation()
* Perform type conversion on input
* @private
* @param {Operation} Operation
* @returns {Function} The operation's run function, wrapped in
* some type conversion logic
@ -49,14 +80,7 @@ export function wrap(Operation) {
const type = Dish.typeEnum(input.constructor.name);
dish.set(input, type);
if (!args) {
args = operation.args.map(extractArg);
} else {
// Allows single arg ops to have arg defined not in array
if (!(args instanceof Array)) {
args = [args];
}
}
args = transformArgs(operation.args, args);
const transformedInput = await dish.get(operation.inputType);
// Allow callback or promsise / async-await
@ -104,7 +128,12 @@ function extractOperationInfo(Operation) {
description: operation.description,
inputType: operation.inputType,
outputType: operation.outputType,
args: Object.assign([], operation.args),
// Make arg names lowercase, no spaces to encourage non-sentence
// caps in repl
args: Object.assign([], operation.args).map((s) => {
s.name = decapitalise(s.name).replace(/ /g, "");
return s;
})
};
}

View File

@ -59,5 +59,27 @@ TestRegister.addApiTests([
}
assert(false);
});
}),
it("should accept arguments in object format for operations", async () => {
const result = await chef.setUnion("1 2 3 4:3 4 5 6", {
itemDelimiter: " ",
sampleDelimiter: ":"
});
assert.equal(result, "1 2 3 4 5 6");
}),
it("should accept just some of the optional arguments being overriden", async () => {
const result = await chef.setIntersection("1 2 3 4 5\\n\\n3 4 5", {
itemDelimiter: " ",
});
assert.equal(result, "3 4 5");
}),
it("should accept no override arguments and just use the default values", async () => {
const result = await chef.powerSet("1,2,3");
assert.equal(result, "\n3\n2\n1\n2,3\n1,3\n1,2\n1,2,3\n");
})
]);

View File

@ -3,7 +3,7 @@
/**
* nodeApi.js
*
* Test node api utilities
* Test node api translateTo function
*
* @author d98762625 [d98762625@gmail.com]
* @copyright Crown Copyright 2018
@ -39,7 +39,10 @@ TestRegister.addApiTests([
}),
it("should be symmetric", async () => {
const result = await chef.setUnion("1 2 3 4:3 4 5 6", [":", " "]);
const result = await chef.setUnion("1 2 3 4:3 4 5 6", {
itemDelimiter: " ",
sampleDelimiter: ":"
});
const bytearray = await chef.translateTo(result, "bytearray");
const translated = await chef.translateTo(bytearray, "string");
assert.equal(translated, "1 2 3 4 5 6");