Parcourir la source

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

d98762625 il y a 7 ans
Parent
commit
0a0316a000
3 fichiers modifiés avec 65 ajouts et 11 suppressions
  1. 38 9
      src/node/apiUtils.mjs
  2. 22 0
      test/tests/nodeApi/nodeApi.mjs
  3. 5 2
      test/tests/nodeApi/translateTo.mjs

+ 38 - 9
src/node/apiUtils.mjs

@@ -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;
+        })
     };
 }
 

+ 22 - 0
test/tests/nodeApi/nodeApi.mjs

@@ -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");
     })
 ]);

+ 5 - 2
test/tests/nodeApi/translateTo.mjs

@@ -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");