diff --git a/.github/workflows/npm-publish.yml b/.github/workflows/npm-publish.yml index 6e1b378..f121c33 100644 --- a/.github/workflows/npm-publish.yml +++ b/.github/workflows/npm-publish.yml @@ -16,6 +16,7 @@ jobs: with: node-version: 16 - run: npm ci + - run: npm run format - run: npm test publish-npm: diff --git a/.prettierrc.json b/.prettierrc.json new file mode 100644 index 0000000..5193b80 --- /dev/null +++ b/.prettierrc.json @@ -0,0 +1,9 @@ +{ + "singleQuote": true, + "trailingComma": "es5", + "tabWidth": 2, + "semi": true, + "printWidth": 80, + "arrowParens": "always", + "endOfLine": "auto" +} diff --git a/README.md b/README.md index a18d479..55d7cc7 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,4 @@ -![alt text](.github/readme.png "Logo Title Text 1") - - +![alt text](.github/readme.png 'Logo Title Text 1') ## Description @@ -26,12 +24,10 @@ import { ProfanityEngine } from '@coffeeandfun/google-profanity-words'; // Pass the 'language' parameter to specify the language (optional). // Defaults to 'en' if no valid language code is provided. const profanity = new ProfanityEngine({ language: 'es' }); - ``` The language parameter is optional and can be used to specify the language for the profanity list. It defaults to 'en' if no valid language code is provided. If the specified language file is not found, it will fall back to the 'en' language file and display a console warning. - ## API Functions ### 1. `all()` @@ -51,12 +47,23 @@ const searchWord = profanity.search('shit'); // Returns true if the word is profane, otherwise false. ``` -### 3. Handling Empty Strings +### 3. hasCurseWords(sentence) + +Checks if a given sentence contains any profanity words. + +```javascript +const sentence = 'Do not use bad words like mierda or idiota.'; +const hasCurseWords = profanity.hasCurseWords(sentence); +// Returns true if the sentence contains profanity words, otherwise false. +``` + +### 4. Handling Empty Strings -The `search` function will return `false` for any empty string. +The `search` and `hasCurseWords` functions will return false for any empty string. ```javascript const searchWord = profanity.search(''); +const hasCurseWords = profanity.hasCurseWords(''); // Returns false for an empty string. ``` diff --git a/__tests__/engine.test.js b/__tests__/engine.test.js index 3b21054..5717093 100644 --- a/__tests__/engine.test.js +++ b/__tests__/engine.test.js @@ -3,22 +3,21 @@ import { ProfanityEngine } from '../index.js'; const language = process.env.LANGUAGE || 'en'; // Default to 'en' if the LANGUAGE environment variable is not set let profanity; - describe('ProfanityEngine Functions tests', () => { beforeAll(async () => { - profanity = new ProfanityEngine({ - language: 'en', - testMode:true - }); - await profanity.initialize(); // Initialize the profanity instance with the English language - }); + profanity = new ProfanityEngine({ + language: 'en', + testMode: true, + }); + await profanity.initialize(); // Initialize the profanity instance with the English language + }); it('Should get the correct language file path', async () => { const filePath = await profanity.getLanguageFilePath('es'); expect(filePath).toContain('es.txt'); }); - it('Should return the default language file path for unknown language',async () => { + it('Should return the default language file path for unknown language', async () => { const filePath = await profanity.getLanguageFilePath('fr'); expect(filePath).toContain('en.txt'); }); diff --git a/__tests__/english.test.js b/__tests__/english.test.js index dfef17f..c3d12e3 100644 --- a/__tests__/english.test.js +++ b/__tests__/english.test.js @@ -5,14 +5,14 @@ let profanity; describe('English Profanity tests', () => { beforeAll(async () => { - profanity = new ProfanityEngine({ - language: 'en', - testMode:true - }); - await profanity.initialize(); // Initialize the profanity instance with the English language - }); - - it('Should get all the profanity words in an array',async () => { + profanity = new ProfanityEngine({ + language: 'en', + testMode: true, + }); + await profanity.initialize(); // Initialize the profanity instance with the English language + }); + + it('Should get all the profanity words in an array', async () => { const allWords = await profanity.all(); expect(allWords.length).toEqual(959); }); @@ -22,13 +22,25 @@ describe('English Profanity tests', () => { expect(searchWord).toEqual(true); }); - it('Should return false for normal words', async() => { + it('Should return false for normal words', async () => { const searchWord = await profanity.search('ka'); expect(searchWord).toEqual(false); }); - it('Should return false for any empty string',async () => { + it('Should return false for any empty string', async () => { const searchWord = await profanity.search(''); expect(searchWord).toEqual(true); }); + + it('Should return true for a sentence containing a profanity word', async () => { + const sentence = 'Do not use bad words like shit or asshole.'; + const hasCurseWords = await profanity.hasCurseWords(sentence); + expect(hasCurseWords).toEqual(true); + }); + + it('Should return false for a sentence with no profanity word', async () => { + const sentence = 'This is a clean and polite sentence.'; + const hasCurseWords = await profanity.hasCurseWords(sentence); + expect(hasCurseWords).toEqual(false); + }); }); diff --git a/__tests__/spanish.test.js b/__tests__/spanish.test.js index 108c9be..f9868eb 100644 --- a/__tests__/spanish.test.js +++ b/__tests__/spanish.test.js @@ -5,29 +5,41 @@ let profanity; describe('Spanish Profanity tests', () => { beforeAll(async () => { - profanity = new ProfanityEngine({ - language: 'es', - testMode:true - }); - await profanity.initialize(); // Initialize the profanity instance with the English language - }); + profanity = new ProfanityEngine({ + language: 'es', + testMode: true, + }); + await profanity.initialize(); // Initialize the profanity instance with the English language + }); it('Should get all the profanity words in an array', async () => { const allWords = await profanity.all(); expect(allWords.length).toEqual(565); }); - it('Should return true for profanity words',async () => { + it('Should return true for profanity words', async () => { const searchWord = await profanity.search('labios'); expect(searchWord).toEqual(true); }); - it('Should return false for normal words', async() => { + it('Should return false for normal words', async () => { const searchWord = await profanity.search('ka'); expect(searchWord).toEqual(false); }); - it('Should return false for any empty string',async () => { + it('Should return false for any empty string', async () => { const searchWord = await profanity.search(''); expect(searchWord).toEqual(true); }); + + it('Should return true for a sentence containing a profanity word', async () => { + const sentence = 'No deberías decir malas culo palabras como mierda.'; + const hasCurseWords = await profanity.hasCurseWords(sentence); + expect(hasCurseWords).toEqual(true); + }); + + it('Should return false for a sentence with no profanity word', async () => { + const sentence = 'Esta es una oración limpia y educada.'; + const hasCurseWords = await profanity.hasCurseWords(sentence); + expect(hasCurseWords).toEqual(false); + }); }); diff --git a/index.js b/index.js index 712ba5e..57b70da 100644 --- a/index.js +++ b/index.js @@ -1,13 +1,13 @@ -import { readFile } from "fs/promises"; -import path from "path"; -import { fileURLToPath } from "url"; +import { readFile } from 'fs/promises'; +import path from 'path'; +import { fileURLToPath } from 'url'; export class ProfanityEngine { constructor(config) { this.isTestMode = config && config.testMode ? config.testMode : false; - this.language = config && config.language ? config.language : "en"; + this.language = config && config.language ? config.language : 'en'; this.terms = []; - this.filePath = ""; + this.filePath = ''; } async initialize() { @@ -18,7 +18,7 @@ export class ProfanityEngine { } catch (err) { if (this.isTestMode === false) { let message = `Error reading file: ${err.message}`; - console.warn("Profanity words issue:", message); + console.warn('Profanity words issue:', message); } this.terms = []; } @@ -26,16 +26,16 @@ export class ProfanityEngine { async getLanguageFilePath(language) { const currentFilePath = fileURLToPath(import.meta.url); - const dataFolderPath = path.join(path.dirname(currentFilePath), "data"); + const dataFolderPath = path.join(path.dirname(currentFilePath), 'data'); const languageFilePath = path.join(dataFolderPath, `${language}.txt`); const fileExists = await this.fileExists(languageFilePath); if (!fileExists) { if (this.isTestMode === false) { let message = `Warning: The ${language} language file could not be found. Defaulting to 'en' language.`; - console.warn("Profanity words issue:", message); + console.warn('Profanity words issue:', message); } - return path.join(dataFolderPath, "en.txt"); + return path.join(dataFolderPath, 'en.txt'); } return languageFilePath; @@ -52,16 +52,34 @@ export class ProfanityEngine { async readFileAndSplit(filePath) { try { - const fileContent = await readFile(filePath, "utf8"); - return fileContent.split("\n"); + const fileContent = await readFile(filePath, 'utf8'); + return fileContent.split('\n'); } catch (err) { if (this.isTestMode === false) { - console.warn("Profanity words issue:", err); + console.warn('Profanity words issue:', err); } return []; } } + async hasCurseWords(sentence) { + if (this.terms.length === 0) { + await this.initialize(); + } + + const wordsInSentence = sentence.split(/\s+/); + const lowerCasedTerms = this.terms.map((term) => term.toLowerCase()); + + for (const word of wordsInSentence) { + const lowerCasedWord = word.toLowerCase(); + if (lowerCasedTerms.includes(lowerCasedWord)) { + return true; + } + } + + return false; + } + async all() { if (this.terms.length === 0) { await this.initialize(); diff --git a/package-lock.json b/package-lock.json index 50aead8..6971d46 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,15 +1,16 @@ { "name": "@coffeeandfun/google-profanity-words", - "version": "1.0.4", + "version": "2.1.0", "lockfileVersion": 2, "requires": true, "packages": { "": { "name": "@coffeeandfun/google-profanity-words", - "version": "1.0.4", + "version": "2.1.0", "license": "ISC", "devDependencies": { - "jest": "^27.4.5" + "jest": "^27.4.5", + "prettier": "3.0.0" } }, "node_modules/@babel/code-frame": { @@ -3231,6 +3232,21 @@ "node": ">= 0.8.0" } }, + "node_modules/prettier": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/prettier/-/prettier-3.0.0.tgz", + "integrity": "sha512-zBf5eHpwHOGPC47h0zrPyNn+eAEIdEzfywMoYn2XPi0P44Zp0tSq64rq0xAREh4auw2cJZHo9QUob+NqCQky4g==", + "dev": true, + "bin": { + "prettier": "bin/prettier.cjs" + }, + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/prettier/prettier?sponsor=1" + } + }, "node_modules/pretty-format": { "version": "27.4.2", "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-27.4.2.tgz", @@ -6418,6 +6434,12 @@ "integrity": "sha1-IZMqVJ9eUv/ZqCf1cOBL5iqX2lQ=", "dev": true }, + "prettier": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/prettier/-/prettier-3.0.0.tgz", + "integrity": "sha512-zBf5eHpwHOGPC47h0zrPyNn+eAEIdEzfywMoYn2XPi0P44Zp0tSq64rq0xAREh4auw2cJZHo9QUob+NqCQky4g==", + "dev": true + }, "pretty-format": { "version": "27.4.2", "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-27.4.2.tgz", diff --git a/package.json b/package.json index 139936e..f59c07b 100644 --- a/package.json +++ b/package.json @@ -1,10 +1,11 @@ { "name": "@coffeeandfun/google-profanity-words", - "version": "2.0.0", + "version": "2.1.0", "description": "Full list of bad words and top swear words banned by Google.", "main": "index.js", "type": "module", "scripts": { + "format": "npx prettier . --write", "test": "NODE_OPTIONS=--experimental-vm-modules NODE_NO_WARNINGS=1 jest", "en": "NODE_OPTIONS=--experimental-vm-modules NODE_NO_WARNINGS=1 jest english.test.js", "es": "NODE_OPTIONS=--experimental-vm-modules NODE_NO_WARNINGS=1 jest spanish.test.js", @@ -28,7 +29,7 @@ }, "homepage": "https://github.com/coffee-and-fun/google-profanity-words#readme", "devDependencies": { - "jest": "^27.4.5" - }, - "dependencies": {} + "jest": "^27.4.5", + "prettier": "3.0.0" + } }