From 995ea1e32f9a2f25579e1ca871c142bc31830ab5 Mon Sep 17 00:00:00 2001 From: Andrew Wright Date: Fri, 19 Oct 2018 11:05:01 -0400 Subject: [PATCH 1/2] feat(profane): support profane phrases and well as words When testing a string for a profane word, or phrase, it needs to validate against the entire string instead of just each word in a string. This allows for testing against word combinations instead of just single word checking. --- lib/badwords.js | 9 ++++----- test/isProfane.js | 7 ++++++- 2 files changed, 10 insertions(+), 6 deletions(-) diff --git a/lib/badwords.js b/lib/badwords.js index d8f007b..6cdf86b 100644 --- a/lib/badwords.js +++ b/lib/badwords.js @@ -25,12 +25,11 @@ var Filter = (function() { * @param {string} string - String to evaluate for profanity. */ Filter.prototype.isProfane = function isProfane(string) { - return string - .split(/\b/) - .map(function(w) { - return w.toLowerCase().replace(this.regex, ''); + return this.list + .filter(function (word) { + const wordExp = new RegExp(`\\b${word.replace(/(\W)/g, '\\$1')}\\b`, 'gi'); + return !this.exclude.includes(word) && wordExp.test(string); }, this) - .filter(this.isProfaneLike, this) .shift() || false; }; diff --git a/test/isProfane.js b/test/isProfane.js index 9bb288e..208b961 100644 --- a/test/isProfane.js +++ b/test/isProfane.js @@ -34,6 +34,11 @@ describe('filter', function(){ it('Should tokenize words according to regex word boundaries', function() { assert(filter.isProfane("that person is an\nasshole")); - }) + }); + + it('Should detect bad word phrases', function () { + filter.addWords('oh no'); + assert(filter.isProfane("oh no! this is profane!")); + }); }); }); From 3247af535cfde5a12572fff3a742a26d7cba84a5 Mon Sep 17 00:00:00 2001 From: Andrew Wright Date: Fri, 19 Oct 2018 11:05:28 -0400 Subject: [PATCH 2/2] style: use consistent spacing in file --- lib/badwords.js | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/lib/badwords.js b/lib/badwords.js index 6cdf86b..b0b84a0 100644 --- a/lib/badwords.js +++ b/lib/badwords.js @@ -1,6 +1,6 @@ var localList = require('./lang.json').words; var baseList = require('badwords-list').array; -var Filter = (function() { +var Filter = (function () { /** * Filter constructor. * @constructor @@ -47,10 +47,10 @@ var Filter = (function() { } return this.list - .map(function(w) { + .map(function (w) { return new RegExp('^' + w.replace(/(\W)/g, '\\$1') + '$', 'gi'); }, this) - .reduce(function(outcome, wordExp) { + .reduce(function (outcome, wordExp) { return outcome || wordExp.test(word); }, false); }; @@ -68,7 +68,7 @@ var Filter = (function() { * @param {string} string - Sentence to filter. */ Filter.prototype.clean = function clean(string) { - return string.split(/\b/).map(function(word) { + return string.split(/\b/).map(function (word) { return this.isProfane(word) ? this.replaceWord(word) : word; }.bind(this)).join(''); }; @@ -76,13 +76,13 @@ var Filter = (function() { /** * Add words to blacklist filter / remove words from whitelist filter * @param {(string|string[])} - */ + */ Filter.prototype.addWords = function addWords(words) { words = (words instanceof Array) ? words : [words]; this.list = this.list.concat(words); - words.forEach(function(word) { - if(!!~this.exclude.indexOf(word)) { + words.forEach(function (word) { + if (!!~this.exclude.indexOf(word)) { this.exclude.splice(this.exclude.indexOf(word), 1); } }, this); @@ -91,7 +91,7 @@ var Filter = (function() { /** * Add words to whitelist filter * @param {...string} word - Word to add to whitelist. - */ + */ Filter.prototype.removeWords = function removeWords() { var words = Array.prototype.slice.call(arguments); this.exclude.push.apply(this.exclude, words);