diff --git a/src/core/config/OperationConfig.json b/src/core/config/OperationConfig.json index 024e5952..fee0ec09 100644 --- a/src/core/config/OperationConfig.json +++ b/src/core/config/OperationConfig.json @@ -210,6 +210,25 @@ } ] }, + "Set Difference": { + "module": "Default", + "description": "Get the Difference of two sets", + "inputType": "string", + "outputType": "string", + "flowControl": false, + "args": [ + { + "name": "Sample delimiter", + "type": "binaryString", + "value": "\\n\\n" + }, + { + "name": "Item delimiter", + "type": "binaryString", + "value": "," + } + ] + }, "Set Intersection": { "module": "Default", "description": "Get the intersection of two sets", diff --git a/src/core/config/modules/Default.mjs b/src/core/config/modules/Default.mjs index 28528882..8a1496fa 100644 --- a/src/core/config/modules/Default.mjs +++ b/src/core/config/modules/Default.mjs @@ -9,6 +9,7 @@ import FromBase32 from "../../operations/FromBase32"; import FromBase64 from "../../operations/FromBase64"; import FromHex from "../../operations/FromHex"; import RawDeflate from "../../operations/RawDeflate"; +import SetDifference from "../../operations/SetDifference"; import SetIntersection from "../../operations/SetIntersection"; import SetOps from "../../operations/SetOps"; import SetUnion from "../../operations/SetUnion"; @@ -24,6 +25,7 @@ OpModules.Default = { "From Base64": FromBase64, "From Hex": FromHex, "Raw Deflate": RawDeflate, + "Set Difference": SetDifference, "Set Intersection": SetIntersection, "": SetOps, "Set Union": SetUnion, diff --git a/src/core/operations/SetDifference.mjs b/src/core/operations/SetDifference.mjs new file mode 100644 index 00000000..6b2d076f --- /dev/null +++ b/src/core/operations/SetDifference.mjs @@ -0,0 +1,86 @@ +/** + * @author d98762625 [d98762625@gmail.com] + * @copyright Crown Copyright 2018 + * @license Apache-2.0 + */ + +import Utils from "../Utils"; +import Operation from "../Operation"; + +/** + * Set Difference operation + */ +class SetDifference extends Operation { + + /** + * Set Difference constructor + */ + constructor() { + super(); + + this.name = "Set Difference"; + this.module = "Default"; + this.description = "Get the Difference of two sets"; + this.inputType = "string"; + this.outputType = "string"; + this.args = [ + { + name: "Sample delimiter", + type: "binaryString", + value: Utils.escapeHtml("\\n\\n") + }, + { + name: "Item delimiter", + type: "binaryString", + value: "," + }, + ]; + } + + /** + * Validate input length + * @param {Object[]} sets + * @throws {Error} if not two sets + */ + validateSampleNumbers(sets) { + if (!sets || (sets.length !== 2)) { + throw "Incorrect number of sets, perhaps you need to modify the sample delimiter or add more samples?"; + } + } + + /** + * Run the difference operation + * @param input + * @param args + */ + run(input, args) { + [this.sampleDelim, this.itemDelimiter] = args; + const sets = input.split(this.sampleDelim); + + try { + this.validateSampleNumbers(sets); + } catch (e) { + return e; + } + + return Utils.escapeHtml(this.runSetDifferencez(...sets.map(s => s.split(this.itemDelimiter)))); + } + + /** + * Get elements in set a that are not in set b + * + * @param {Object[]} a + * @param {Object[]} b + * @returns {Object[]} + */ + runSetDifference(a, b) { + return a + .filter((item) => { + return b.indexOf(item) === -1; + }) + .join(this.itemDelimiter); + } + +} + +export default SetDifference; diff --git a/src/core/operations/SetUnion.mjs b/src/core/operations/SetUnion.mjs index bde0cae7..bfe39d11 100644 --- a/src/core/operations/SetUnion.mjs +++ b/src/core/operations/SetUnion.mjs @@ -1,3 +1,9 @@ +/** + * @author d98762625 [d98762625@gmail.com] + * @copyright Crown Copyright 2018 + * @license Apache-2.0 + */ + import Utils from "../Utils"; import Operation from "../Operation"; diff --git a/src/core/operations/index.mjs b/src/core/operations/index.mjs index ae6c12df..fce3dd9b 100644 --- a/src/core/operations/index.mjs +++ b/src/core/operations/index.mjs @@ -12,6 +12,7 @@ import Gunzip from "./Gunzip"; import Gzip from "./Gzip"; import RawDeflate from "./RawDeflate"; import RawInflate from "./RawInflate"; +import SetDifference from "./SetDifference"; import SetIntersection from "./SetIntersection"; import SetOps from "./SetOps"; import SetUnion from "./SetUnion"; @@ -32,6 +33,7 @@ export { Gzip, RawDeflate, RawInflate, + SetDifference, SetIntersection, SetOps, SetUnion, diff --git a/test/index.mjs b/test/index.mjs index 73638537..fdcd3102 100644 --- a/test/index.mjs +++ b/test/index.mjs @@ -49,8 +49,7 @@ import "./tests/operations/Base64"; // import "./tests/operations/SeqUtils.js"; import "./tests/operations/SetUnion"; import "./tests/operations/SetIntersection"; - - +import "./tests/operations/SetDifference"; let allTestsPassing = true; const testStatusCounts = { diff --git a/test/tests/operations/SetDifference.mjs b/test/tests/operations/SetDifference.mjs new file mode 100644 index 00000000..3bc91d3f --- /dev/null +++ b/test/tests/operations/SetDifference.mjs @@ -0,0 +1,56 @@ +/** + * Set Difference tests. + * + * @author d98762625 + * + * @copyright Crown Copyright 2018 + * @license Apache-2.0 + */ +import TestRegister from "../../TestRegister"; + +TestRegister.addTests([ + { + name: "Set Difference", + input: "1 2 3 4 5\n\n3 4 5 6 7", + expectedOutput: "1 2", + recipeConfig: [ + { + op: "Set Difference", + args: ["\n\n", " "], + }, + ], + }, + { + name: "Set Difference: wrong sample count", + input: "1 2 3 4 5_3_4 5 6 7", + expectedOutput: "Incorrect number of sets, perhaps you need to modify the sample delimiter or add more samples?", + recipeConfig: [ + { + op: "Set Difference", + args: [" ", "_"], + }, + ], + }, + { + name: "Set Difference: item delimiter", + input: "1;2;3;4;5\n\n3;4;5;6;7", + expectedOutput: "1;2", + recipeConfig: [ + { + op: "Set Difference", + args: ["\n\n", ";"], + }, + ], + }, + { + name: "Set Difference: sample delimiter", + input: "1;2;3;4;5===3;4;5;6;7", + expectedOutput: "1;2", + recipeConfig: [ + { + op: "Set Difference", + args: ["===", ";"], + }, + ], + }, +]); diff --git a/test/tests/operations/SetIntersection.mjs b/test/tests/operations/SetIntersection.mjs index b6121893..83809b6e 100644 --- a/test/tests/operations/SetIntersection.mjs +++ b/test/tests/operations/SetIntersection.mjs @@ -1,9 +1,9 @@ /** - * Set Operations tests. + * Set Intersection tests. * * @author d98762625 * - * @copyright Crown Copyright 2017 + * @copyright Crown Copyright 2018 * @license Apache-2.0 */ import TestRegister from "../../TestRegister"; diff --git a/test/tests/operations/SetUnion.mjs b/test/tests/operations/SetUnion.mjs index f214549a..a78bdc36 100644 --- a/test/tests/operations/SetUnion.mjs +++ b/test/tests/operations/SetUnion.mjs @@ -1,9 +1,9 @@ /** - * Set Operations tests. + * Set Union tests. * * @author d98762625 * - * @copyright Crown Copyright 2017 + * @copyright Crown Copyright 2018 * @license Apache-2.0 */ import TestRegister from "../../TestRegister";