From dea214bd2e82c7d8457db0ee58c58d62596a2a10 Mon Sep 17 00:00:00 2001 From: toby Date: Fri, 21 Apr 2017 23:06:59 -0400 Subject: [PATCH 1/3] Add Head and Tail operations --- src/core/config/OperationConfig.js | 64 ++++++++- src/core/operations/StrUtils.js | 55 ++++++++ test/tests/operations/StrUtils.js | 220 +++++++++++++++++++++++++++++ 3 files changed, 338 insertions(+), 1 deletion(-) diff --git a/src/core/config/OperationConfig.js b/src/core/config/OperationConfig.js index 16f6f1b7..777f21f3 100755 --- a/src/core/config/OperationConfig.js +++ b/src/core/config/OperationConfig.js @@ -3196,7 +3196,69 @@ const OperationConfig = { outputType: "html", args: [ ] - } + }, + "Head": { + description: [ + "Like the UNIX head utility.", + "
", + "Gets the first $Number of lines.", + "
", + "Optionally you can select all but the last $Number of lines.", + "
", + "The delimiter can be changed so that instead of lines, fields (i.e. commas) are selected instead.", + ].join("\n"), + run: StrUtils.runHead, + inputType: "string", + outputType: "string", + args: [ + { + name: "Delimiter", + type: "option", + value: StrUtils.DELIMITER_OPTIONS + }, + { + name: "Number", + type: "number", + value: 10, + }, + { + name: "All but last $Number of lines", + type: "boolean", + value: false, + }, + ] + }, + "Tail": { + description: [ + "Like the UNIX tail utility.", + "
", + "Gets the last $Number of lines.", + "
", + "Optionally you can select all lines after line $Number.", + "
", + "The delimiter can be changed so that instead of lines, fields (i.e. commas) are selected instead.", + ].join("\n"), + run: StrUtils.runTail, + inputType: "string", + outputType: "string", + args: [ + { + name: "Delimiter", + type: "option", + value: StrUtils.DELIMITER_OPTIONS + }, + { + name: "Number", + type: "number", + value: 10, + }, + { + name: "Start from line $Number", + type: "boolean", + value: false, + }, + ] + }, }; export default OperationConfig; diff --git a/src/core/operations/StrUtils.js b/src/core/operations/StrUtils.js index 816d4abc..4ba0b18e 100755 --- a/src/core/operations/StrUtils.js +++ b/src/core/operations/StrUtils.js @@ -537,6 +537,61 @@ const StrUtils = { return output; }, + /** + * Head lines operation. + * + * @param {string} input + * @param {Object[]} args + * @returns {string} + */ + runHead: function(input, args) { + let delimiter = args[0], + number = args[1], + allBut = args[2]; + + delimiter = Utils.charRep[delimiter]; + let splitInput = input.split(delimiter); + + return splitInput + .filter((line, lineIndex) => { + lineIndex += 1; + + if (allBut) { + return lineIndex <= splitInput.length - number; + } else { + return lineIndex <= number; + } + }) + .join(delimiter); + }, + + /** + * Tail lines operation. + * + * @param {string} input + * @param {Object[]} args + * @returns {string} + */ + runTail: function(input, args) { + let delimiter = args[0], + number = args[1], + allBut = args[2]; + + delimiter = Utils.charRep[delimiter]; + let splitInput = input.split(delimiter); + + return splitInput + .filter((line, lineIndex) => { + lineIndex += 1; + + if (allBut) { + return lineIndex >= number; + } else { + return lineIndex > splitInput.length - number; + } + }) + .join(delimiter); + }, }; export default StrUtils; diff --git a/test/tests/operations/StrUtils.js b/test/tests/operations/StrUtils.js index ada89137..d1af9dd8 100644 --- a/test/tests/operations/StrUtils.js +++ b/test/tests/operations/StrUtils.js @@ -34,4 +34,224 @@ TestRegister.addTests([ } ], }, + { + name: "Head 0", + input: [1, 2, 3, 4, 5, 6].join("\n"), + expectedOutput: [].join("\n"), + recipeConfig: [ + { + "op": "Head", + "args": ["Line feed", 0, false] + } + ], + }, + { + name: "Head 1", + input: [1, 2, 3, 4, 5, 6].join("\n"), + expectedOutput: [1].join("\n"), + recipeConfig: [ + { + "op": "Head", + "args": ["Line feed", 1, false] + } + ], + }, + { + name: "Head 2", + input: [1, 2, 3, 4, 5, 6].join("\n"), + expectedOutput: [1, 2].join("\n"), + recipeConfig: [ + { + "op": "Head", + "args": ["Line feed", 2, false] + } + ], + }, + { + name: "Head 6", + input: [1, 2, 3, 4, 5, 6].join("\n"), + expectedOutput: [1, 2, 3, 4, 5, 6].join("\n"), + recipeConfig: [ + { + "op": "Head", + "args": ["Line feed", 6, false] + } + ], + }, + { + name: "Head big", + input: [1, 2, 3, 4, 5, 6].join("\n"), + expectedOutput: [1, 2, 3, 4, 5, 6].join("\n"), + recipeConfig: [ + { + "op": "Head", + "args": ["Line feed", 100, false] + } + ], + }, + { + name: "Head all but 0", + input: [1, 2, 3, 4, 5, 6].join("\n"), + expectedOutput: [1, 2, 3, 4, 5, 6].join("\n"), + recipeConfig: [ + { + "op": "Head", + "args": ["Line feed", 0, true] + } + ], + }, + { + name: "Head all but 1", + input: [1, 2, 3, 4, 5, 6].join("\n"), + expectedOutput: [1, 2, 3, 4, 5].join("\n"), + recipeConfig: [ + { + "op": "Head", + "args": ["Line feed", 1, true] + } + ], + }, + { + name: "Head all but 2", + input: [1, 2, 3, 4, 5, 6].join("\n"), + expectedOutput: [1, 2, 3, 4].join("\n"), + recipeConfig: [ + { + "op": "Head", + "args": ["Line feed", 2, true] + } + ], + }, + { + name: "Head all but 6", + input: [1, 2, 3, 4, 5, 6].join("\n"), + expectedOutput: [].join("\n"), + recipeConfig: [ + { + "op": "Head", + "args": ["Line feed", 6, true] + } + ], + }, + { + name: "Head all but big", + input: [1, 2, 3, 4, 5, 6].join("\n"), + expectedOutput: [].join("\n"), + recipeConfig: [ + { + "op": "Head", + "args": ["Line feed", 100, true] + } + ], + }, + { + name: "Tail 0", + input: [1, 2, 3, 4, 5, 6].join("\n"), + expectedOutput: [].join("\n"), + recipeConfig: [ + { + "op": "Tail", + "args": ["Line feed", 0, false] + } + ], + }, + { + name: "Tail 1", + input: [1, 2, 3, 4, 5, 6].join("\n"), + expectedOutput: [6].join("\n"), + recipeConfig: [ + { + "op": "Tail", + "args": ["Line feed", 1, false] + } + ], + }, + { + name: "Tail 2", + input: [1, 2, 3, 4, 5, 6].join("\n"), + expectedOutput: [5, 6].join("\n"), + recipeConfig: [ + { + "op": "Tail", + "args": ["Line feed", 2, false] + } + ], + }, + { + name: "Tail 6", + input: [1, 2, 3, 4, 5, 6].join("\n"), + expectedOutput: [1, 2, 3, 4, 5, 6].join("\n"), + recipeConfig: [ + { + "op": "Tail", + "args": ["Line feed", 6, false] + } + ], + }, + { + name: "Tail big", + input: [1, 2, 3, 4, 5, 6].join("\n"), + expectedOutput: [1, 2, 3, 4, 5, 6].join("\n"), + recipeConfig: [ + { + "op": "Tail", + "args": ["Line feed", 100, false] + } + ], + }, + { + name: "Tail all but 0", + input: [1, 2, 3, 4, 5, 6].join("\n"), + expectedOutput: [1, 2, 3, 4, 5, 6].join("\n"), + recipeConfig: [ + { + "op": "Tail", + "args": ["Line feed", 0, true] + } + ], + }, + { + name: "Tail all but 1", + input: [1, 2, 3, 4, 5, 6].join("\n"), + expectedOutput: [1, 2, 3, 4, 5, 6].join("\n"), + recipeConfig: [ + { + "op": "Tail", + "args": ["Line feed", 1, true] + } + ], + }, + { + name: "Tail all but 2", + input: [1, 2, 3, 4, 5, 6].join("\n"), + expectedOutput: [2, 3, 4, 5, 6].join("\n"), + recipeConfig: [ + { + "op": "Tail", + "args": ["Line feed", 2, true] + } + ], + }, + { + name: "Tail all but 6", + input: [1, 2, 3, 4, 5, 6].join("\n"), + expectedOutput: [6].join("\n"), + recipeConfig: [ + { + "op": "Tail", + "args": ["Line feed", 6, true] + } + ], + }, + { + name: "Tail all but big", + input: [1, 2, 3, 4, 5, 6].join("\n"), + expectedOutput: [].join("\n"), + recipeConfig: [ + { + "op": "Tail", + "args": ["Line feed", 100, true] + } + ], + }, ]); From d081ff745dd8ea95736722f12123c44eb35aea54 Mon Sep 17 00:00:00 2001 From: n1474335 Date: Sun, 23 Apr 2017 18:05:00 +0100 Subject: [PATCH 2/3] Added Head and Tail to Utils category and replaced 'AllBut' argument functionality with support for negative values of n. --- src/core/config/Categories.js | 2 + src/core/config/OperationConfig.js | 18 ++--- src/core/operations/StrUtils.js | 111 +++++++++++++++-------------- 3 files changed, 62 insertions(+), 69 deletions(-) diff --git a/src/core/config/Categories.js b/src/core/config/Categories.js index 1b068644..da0c9f0a 100755 --- a/src/core/config/Categories.js +++ b/src/core/config/Categories.js @@ -162,6 +162,8 @@ const Categories = [ "Unique", "Split", "Filter", + "Head", + "Tail", "Count occurrences", "Expand alphabet range", "Parse escaped string", diff --git a/src/core/config/OperationConfig.js b/src/core/config/OperationConfig.js index 777f21f3..ca6bdbbd 100755 --- a/src/core/config/OperationConfig.js +++ b/src/core/config/OperationConfig.js @@ -3201,9 +3201,9 @@ const OperationConfig = { description: [ "Like the UNIX head utility.", "
", - "Gets the first $Number of lines.", + "Gets the first n lines.", "
", - "Optionally you can select all but the last $Number of lines.", + "You can select all but the last n lines by entering a negative value for n.", "
", "The delimiter can be changed so that instead of lines, fields (i.e. commas) are selected instead.", ].join("\n"), @@ -3221,20 +3221,15 @@ const OperationConfig = { type: "number", value: 10, }, - { - name: "All but last $Number of lines", - type: "boolean", - value: false, - }, ] }, "Tail": { description: [ "Like the UNIX tail utility.", "
", - "Gets the last $Number of lines.", + "Gets the last n lines.", "
", - "Optionally you can select all lines after line $Number.", + "Optionally you can select all lines after line n by entering a negative value for n.", "
", "The delimiter can be changed so that instead of lines, fields (i.e. commas) are selected instead.", ].join("\n"), @@ -3252,11 +3247,6 @@ const OperationConfig = { type: "number", value: 10, }, - { - name: "Start from line $Number", - type: "boolean", - value: false, - }, ] }, }; diff --git a/src/core/operations/StrUtils.js b/src/core/operations/StrUtils.js index 4ba0b18e..00d2c561 100755 --- a/src/core/operations/StrUtils.js +++ b/src/core/operations/StrUtils.js @@ -460,6 +460,62 @@ const StrUtils = { }, + /** + * Head lines operation. + * + * @param {string} input + * @param {Object[]} args + * @returns {string} + */ + runHead: function(input, args) { + let delimiter = args[0], + number = args[1]; + + delimiter = Utils.charRep[delimiter]; + let splitInput = input.split(delimiter); + + return splitInput + .filter((line, lineIndex) => { + lineIndex += 1; + + if (number < 0) { + return lineIndex <= splitInput.length + number; + } else { + return lineIndex <= number; + } + }) + .join(delimiter); + }, + + + /** + * Tail lines operation. + * + * @param {string} input + * @param {Object[]} args + * @returns {string} + */ + runTail: function(input, args) { + let delimiter = args[0], + number = args[1]; + + delimiter = Utils.charRep[delimiter]; + let splitInput = input.split(delimiter); + + return splitInput + .filter((line, lineIndex) => { + lineIndex += 1; + + if (number < 0) { + return lineIndex > -number; + } else { + return lineIndex > splitInput.length - number; + } + }) + .join(delimiter); + }, + + /** * Adds HTML highlights to matches within a string. * @@ -537,61 +593,6 @@ const StrUtils = { return output; }, - /** - * Head lines operation. - * - * @param {string} input - * @param {Object[]} args - * @returns {string} - */ - runHead: function(input, args) { - let delimiter = args[0], - number = args[1], - allBut = args[2]; - - delimiter = Utils.charRep[delimiter]; - let splitInput = input.split(delimiter); - - return splitInput - .filter((line, lineIndex) => { - lineIndex += 1; - - if (allBut) { - return lineIndex <= splitInput.length - number; - } else { - return lineIndex <= number; - } - }) - .join(delimiter); - }, - - /** - * Tail lines operation. - * - * @param {string} input - * @param {Object[]} args - * @returns {string} - */ - runTail: function(input, args) { - let delimiter = args[0], - number = args[1], - allBut = args[2]; - - delimiter = Utils.charRep[delimiter]; - let splitInput = input.split(delimiter); - - return splitInput - .filter((line, lineIndex) => { - lineIndex += 1; - - if (allBut) { - return lineIndex >= number; - } else { - return lineIndex > splitInput.length - number; - } - }) - .join(delimiter); - }, }; export default StrUtils; From 2c0f0d9a202f41e24be453d567834d472ec540b2 Mon Sep 17 00:00:00 2001 From: n1474335 Date: Sun, 23 Apr 2017 18:29:54 +0100 Subject: [PATCH 3/3] Changed Head and Tail tests to match new 'AllBut' configuration. --- test/tests/operations/StrUtils.js | 64 ++++++++++--------------------- 1 file changed, 21 insertions(+), 43 deletions(-) diff --git a/test/tests/operations/StrUtils.js b/test/tests/operations/StrUtils.js index d1af9dd8..1450d1ba 100644 --- a/test/tests/operations/StrUtils.js +++ b/test/tests/operations/StrUtils.js @@ -41,7 +41,7 @@ TestRegister.addTests([ recipeConfig: [ { "op": "Head", - "args": ["Line feed", 0, false] + "args": ["Line feed", 0] } ], }, @@ -52,7 +52,7 @@ TestRegister.addTests([ recipeConfig: [ { "op": "Head", - "args": ["Line feed", 1, false] + "args": ["Line feed", 1] } ], }, @@ -63,7 +63,7 @@ TestRegister.addTests([ recipeConfig: [ { "op": "Head", - "args": ["Line feed", 2, false] + "args": ["Line feed", 2] } ], }, @@ -74,7 +74,7 @@ TestRegister.addTests([ recipeConfig: [ { "op": "Head", - "args": ["Line feed", 6, false] + "args": ["Line feed", 6] } ], }, @@ -85,18 +85,7 @@ TestRegister.addTests([ recipeConfig: [ { "op": "Head", - "args": ["Line feed", 100, false] - } - ], - }, - { - name: "Head all but 0", - input: [1, 2, 3, 4, 5, 6].join("\n"), - expectedOutput: [1, 2, 3, 4, 5, 6].join("\n"), - recipeConfig: [ - { - "op": "Head", - "args": ["Line feed", 0, true] + "args": ["Line feed", 100] } ], }, @@ -107,7 +96,7 @@ TestRegister.addTests([ recipeConfig: [ { "op": "Head", - "args": ["Line feed", 1, true] + "args": ["Line feed", -1] } ], }, @@ -118,7 +107,7 @@ TestRegister.addTests([ recipeConfig: [ { "op": "Head", - "args": ["Line feed", 2, true] + "args": ["Line feed", -2] } ], }, @@ -129,7 +118,7 @@ TestRegister.addTests([ recipeConfig: [ { "op": "Head", - "args": ["Line feed", 6, true] + "args": ["Line feed", -6] } ], }, @@ -140,7 +129,7 @@ TestRegister.addTests([ recipeConfig: [ { "op": "Head", - "args": ["Line feed", 100, true] + "args": ["Line feed", -100] } ], }, @@ -151,7 +140,7 @@ TestRegister.addTests([ recipeConfig: [ { "op": "Tail", - "args": ["Line feed", 0, false] + "args": ["Line feed", 0] } ], }, @@ -162,7 +151,7 @@ TestRegister.addTests([ recipeConfig: [ { "op": "Tail", - "args": ["Line feed", 1, false] + "args": ["Line feed", 1] } ], }, @@ -173,7 +162,7 @@ TestRegister.addTests([ recipeConfig: [ { "op": "Tail", - "args": ["Line feed", 2, false] + "args": ["Line feed", 2] } ], }, @@ -184,7 +173,7 @@ TestRegister.addTests([ recipeConfig: [ { "op": "Tail", - "args": ["Line feed", 6, false] + "args": ["Line feed", 6] } ], }, @@ -195,51 +184,40 @@ TestRegister.addTests([ recipeConfig: [ { "op": "Tail", - "args": ["Line feed", 100, false] - } - ], - }, - { - name: "Tail all but 0", - input: [1, 2, 3, 4, 5, 6].join("\n"), - expectedOutput: [1, 2, 3, 4, 5, 6].join("\n"), - recipeConfig: [ - { - "op": "Tail", - "args": ["Line feed", 0, true] + "args": ["Line feed", 100] } ], }, { name: "Tail all but 1", input: [1, 2, 3, 4, 5, 6].join("\n"), - expectedOutput: [1, 2, 3, 4, 5, 6].join("\n"), + expectedOutput: [2, 3, 4, 5, 6].join("\n"), recipeConfig: [ { "op": "Tail", - "args": ["Line feed", 1, true] + "args": ["Line feed", -1] } ], }, { name: "Tail all but 2", input: [1, 2, 3, 4, 5, 6].join("\n"), - expectedOutput: [2, 3, 4, 5, 6].join("\n"), + expectedOutput: [3, 4, 5, 6].join("\n"), recipeConfig: [ { "op": "Tail", - "args": ["Line feed", 2, true] + "args": ["Line feed", -2] } ], }, { name: "Tail all but 6", input: [1, 2, 3, 4, 5, 6].join("\n"), - expectedOutput: [6].join("\n"), + expectedOutput: [].join("\n"), recipeConfig: [ { "op": "Tail", - "args": ["Line feed", 6, true] + "args": ["Line feed", -6] } ], }, @@ -250,7 +228,7 @@ TestRegister.addTests([ recipeConfig: [ { "op": "Tail", - "args": ["Line feed", 100, true] + "args": ["Line feed", -100] } ], },