From 340b34b278735433ee33738e52f7eba2cdbddcf1 Mon Sep 17 00:00:00 2001 From: Alex Shi Date: Mon, 7 Feb 2022 10:15:21 -0500 Subject: [PATCH 1/6] Rename string replace and put in helpers --- helpers.js | 1 + helpers/strReplace.js | 25 +++++++++++++++++++ spec/helpers.js | 1 + spec/helpers/strReplace.js | 51 ++++++++++++++++++++++++++++++++++++++ 4 files changed, 78 insertions(+) create mode 100644 helpers/strReplace.js create mode 100644 spec/helpers/strReplace.js diff --git a/helpers.js b/helpers.js index 78cd1ba..f8c725a 100644 --- a/helpers.js +++ b/helpers.js @@ -44,6 +44,7 @@ const helpersList = [ 'setURLQueryParam', 'snippets', 'stripQuerystring', + 'strReplace', 'stylesheet', 'thirdParty', 'toLowerCase', diff --git a/helpers/strReplace.js b/helpers/strReplace.js new file mode 100644 index 0000000..73adba5 --- /dev/null +++ b/helpers/strReplace.js @@ -0,0 +1,25 @@ +'use strict'; + +const factory = () => { + return function(string, substr, newSubstr, token) { + if (typeof string !== 'string' || typeof substr !== 'string' || typeof newSubstr !== 'string') { + return 'Invalid Input'; + } + + if (token && typeof token === 'string') { + return string.replace(new RegExp(escapeRegex(substr), token), newSubstr); + } else { + return string.replace(new RegExp(escapeRegex(substr), 'g'), newSubstr); + } + + }; +}; + +function escapeRegex(string) { + return string.replace(/[-\\^$*+?.()|[\]{}]/g, "\\$&"); +} + +module.exports = [{ + name: 'strReplace', + factory: factory, +}]; diff --git a/spec/helpers.js b/spec/helpers.js index deb2683..b3e24c6 100644 --- a/spec/helpers.js +++ b/spec/helpers.js @@ -63,6 +63,7 @@ describe('helper registration', () => { 'setURLQueryParam', 'snippet', 'stripQuerystring', + 'strReplace', 'stylesheet', 'after', 'arrayify', diff --git a/spec/helpers/strReplace.js b/spec/helpers/strReplace.js new file mode 100644 index 0000000..4a467f5 --- /dev/null +++ b/spec/helpers/strReplace.js @@ -0,0 +1,51 @@ +const Lab = require('lab'), + lab = exports.lab = Lab.script(), + describe = lab.experiment, + it = lab.it, + testRunner = require('../spec-helpers').testRunner; + +describe('strReplace helper', function() { + const context = { + string: "My name is Albe Albe Albe", + substr: "Albe", + newSubstr: "Alex", + object: {} + }; + + const runTestCases = testRunner({context}); + + it('should replace all by default', function(done) { + runTestCases([ + { + input: '{{strReplace string substr newSubstr}}', + output: 'My name is Alex Alex Alex', + }, + { + input: '{{strReplace "Your name is none" "none" "Bob"}}', + output: 'Your name is Bob', + }, + ], done); + }); + + it('should replace one if given token', function(done) { + runTestCases([ + { + input: '{{strReplace string substr newSubstr "i"}}', + output: 'My name is Alex Albe Albe', + }, + ], done); + }); + + it('should only handle string', function(done) { + runTestCases([ + { + input: '{{strReplace 5 5 5}}', + output: 'Invalid Input', + }, + { + input: '{{strReplace object "none" "Bob"}}', + output: 'Invalid Input', + }, + ], done); + }); +}); From 7df11ad467193fd95cad8a615c20e62066bebc00 Mon Sep 17 00:00:00 2001 From: Alex Shi Date: Tue, 8 Feb 2022 12:55:50 -0500 Subject: [PATCH 2/6] Update String Replace input options --- helpers/strReplace.js | 30 ++++++++++++++++++++++++------ spec/helpers/strReplace.js | 22 +++++++++++++++++++--- 2 files changed, 43 insertions(+), 9 deletions(-) diff --git a/helpers/strReplace.js b/helpers/strReplace.js index 73adba5..92e87a4 100644 --- a/helpers/strReplace.js +++ b/helpers/strReplace.js @@ -1,17 +1,30 @@ 'use strict'; const factory = () => { - return function(string, substr, newSubstr, token) { - if (typeof string !== 'string' || typeof substr !== 'string' || typeof newSubstr !== 'string') { + return function(str, substr, newSubstr, iteration) { + if (typeof str !== 'string' || typeof substr !== 'string' || typeof newSubstr !== 'string') { return 'Invalid Input'; } - if (token && typeof token === 'string') { - return string.replace(new RegExp(escapeRegex(substr), token), newSubstr); - } else { - return string.replace(new RegExp(escapeRegex(substr), 'g'), newSubstr); + if (typeof iteration !== 'number') { + return str.replace(new RegExp(escapeRegex(substr), 'g'), newSubstr); } + const occurrence = getOccurrences(str, substr); + + if (iteration > 0 && occurrence > 0) { + if (iteration >= occurrence) { + return str.replace(new RegExp(escapeRegex(substr), 'g'), newSubstr); + } else { + let result = str; + for (let i = 0; i < iteration; i++) { + result = result.replace(substr, newSubstr); + } + return result; + } + } else { + return str; + } }; }; @@ -19,6 +32,11 @@ function escapeRegex(string) { return string.replace(/[-\\^$*+?.()|[\]{}]/g, "\\$&"); } +function getOccurrences(str, substr) { + const matches = str.match(new RegExp(escapeRegex(substr),'g')); + return matches ? matches.length : 0; +} + module.exports = [{ name: 'strReplace', factory: factory, diff --git a/spec/helpers/strReplace.js b/spec/helpers/strReplace.js index 4a467f5..38bf4fc 100644 --- a/spec/helpers/strReplace.js +++ b/spec/helpers/strReplace.js @@ -27,11 +27,27 @@ describe('strReplace helper', function() { ], done); }); - it('should replace one if given token', function(done) { + it('should replace multiple if given quantity', function(done) { runTestCases([ { - input: '{{strReplace string substr newSubstr "i"}}', - output: 'My name is Alex Albe Albe', + input: '{{strReplace string substr newSubstr -5}}', + output: 'My name is Albe Albe Albe', + }, + { + input: '{{strReplace string substr newSubstr 0}}', + output: 'My name is Albe Albe Albe', + }, + { + input: '{{strReplace string substr newSubstr 2}}', + output: 'My name is Alex Alex Albe', + }, + { + input: '{{strReplace string substr newSubstr 4}}', + output: 'My name is Alex Alex Alex', + }, + { + input: '{{strReplace string substr newSubstr 100}}', + output: 'My name is Alex Alex Alex', }, ], done); }); From 6b2867f64d408d860e1eaa5035ffbf556a308db2 Mon Sep 17 00:00:00 2001 From: Alex Shi Date: Tue, 15 Feb 2022 09:34:56 -0500 Subject: [PATCH 3/6] Update input type checking method --- helpers/strReplace.js | 17 ++++++++++++++--- 1 file changed, 14 insertions(+), 3 deletions(-) diff --git a/helpers/strReplace.js b/helpers/strReplace.js index 92e87a4..cd8c553 100644 --- a/helpers/strReplace.js +++ b/helpers/strReplace.js @@ -1,9 +1,20 @@ 'use strict'; +const common = require('./lib/common.js'); +const utils = require('handlebars-utils'); -const factory = () => { +const factory = globals => { return function(str, substr, newSubstr, iteration) { - if (typeof str !== 'string' || typeof substr !== 'string' || typeof newSubstr !== 'string') { - return 'Invalid Input'; + str = common.unwrapIfSafeString(globals.handlebars, str); + substr = common.unwrapIfSafeString(globals.handlebars, substr); + newSubstr = common.unwrapIfSafeString(globals.handlebars, newSubstr); + iteration = common.unwrapIfSafeString(globals.handlebars, iteration); + + if (!utils.isString(str)){ + throw new TypeError("Invalid query parameter string passed to strReplace"); + } else if (!utils.isString(substr)){ + throw new TypeError("Invalid query paramter substring passed to strReplace"); + } else if(!utils.isString(newSubstr)) { + throw new TypeError("Invalid query parameter new substring passed to strReplace"); } if (typeof iteration !== 'number') { From fd1a41a4868b087dfba9c7496652a9f631bf4b8e Mon Sep 17 00:00:00 2001 From: Alex Shi Date: Wed, 16 Feb 2022 15:03:27 -0500 Subject: [PATCH 4/6] Update string replace test cases to handle error --- spec/helpers/strReplace.js | 23 ++++++++++++----------- 1 file changed, 12 insertions(+), 11 deletions(-) diff --git a/spec/helpers/strReplace.js b/spec/helpers/strReplace.js index 38bf4fc..f273e0f 100644 --- a/spec/helpers/strReplace.js +++ b/spec/helpers/strReplace.js @@ -2,7 +2,9 @@ const Lab = require('lab'), lab = exports.lab = Lab.script(), describe = lab.experiment, it = lab.it, - testRunner = require('../spec-helpers').testRunner; + specHelpers = require('../spec-helpers'), + testRunner = require('../spec-helpers').testRunner, + renderString = specHelpers.renderString;; describe('strReplace helper', function() { const context = { @@ -53,15 +55,14 @@ describe('strReplace helper', function() { }); it('should only handle string', function(done) { - runTestCases([ - { - input: '{{strReplace 5 5 5}}', - output: 'Invalid Input', - }, - { - input: '{{strReplace object "none" "Bob"}}', - output: 'Invalid Input', - }, - ], done); + renderString('{{strReplace object "none" "Bob"}}').catch(e => { + renderString('{{strReplace "none" 3 "Bob"}}').catch(e => { + renderString('{{strReplace "none" "Bob" object}}').catch(e => { + renderString('{{strReplace string substr newSubstr "3"}}').catch(e => { + done(); + }); + }); + }); + }); }); }); From 71c63edd44c8ae980e9d9a85e8ab0c8dcb2eee24 Mon Sep 17 00:00:00 2001 From: Alex Shi Date: Wed, 23 Feb 2022 10:00:52 -0500 Subject: [PATCH 5/6] Update throw error message --- spec/helpers/strReplace.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/spec/helpers/strReplace.js b/spec/helpers/strReplace.js index f273e0f..aad779c 100644 --- a/spec/helpers/strReplace.js +++ b/spec/helpers/strReplace.js @@ -54,7 +54,7 @@ describe('strReplace helper', function() { ], done); }); - it('should only handle string', function(done) { + it('should throw error if parameters have invalid type', function(done) { renderString('{{strReplace object "none" "Bob"}}').catch(e => { renderString('{{strReplace "none" 3 "Bob"}}').catch(e => { renderString('{{strReplace "none" "Bob" object}}').catch(e => { From e95ce8cbfe0a1551b57257094f751f86b54b6577 Mon Sep 17 00:00:00 2001 From: Jared Yap Date: Wed, 23 Feb 2022 09:15:06 -0800 Subject: [PATCH 6/6] updated phrasing of error --- spec/helpers/strReplace.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/spec/helpers/strReplace.js b/spec/helpers/strReplace.js index aad779c..142190d 100644 --- a/spec/helpers/strReplace.js +++ b/spec/helpers/strReplace.js @@ -54,7 +54,7 @@ describe('strReplace helper', function() { ], done); }); - it('should throw error if parameters have invalid type', function(done) { + it('should throw an exception if the parameters have an invalid type', function(done) { renderString('{{strReplace object "none" "Bob"}}').catch(e => { renderString('{{strReplace "none" 3 "Bob"}}').catch(e => { renderString('{{strReplace "none" "Bob" object}}').catch(e => {