Skip to content

Commit 9e55efc

Browse files
Merge pull request #18 from coffee-and-fun/search-support
Search support
2 parents 1456ee0 + 3fd9c86 commit 9e55efc

File tree

9 files changed

+134
-53
lines changed

9 files changed

+134
-53
lines changed

.github/workflows/npm-publish.yml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ jobs:
1616
with:
1717
node-version: 16
1818
- run: npm ci
19+
- run: npm run format
1920
- run: npm test
2021

2122
publish-npm:

.prettierrc.json

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
{
2+
"singleQuote": true,
3+
"trailingComma": "es5",
4+
"tabWidth": 2,
5+
"semi": true,
6+
"printWidth": 80,
7+
"arrowParens": "always",
8+
"endOfLine": "auto"
9+
}

README.md

Lines changed: 14 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,4 @@
1-
![alt text](.github/readme.png "Logo Title Text 1")
2-
3-
1+
![alt text](.github/readme.png 'Logo Title Text 1')
42

53
## Description
64

@@ -26,12 +24,10 @@ import { ProfanityEngine } from '@coffeeandfun/google-profanity-words';
2624
// Pass the 'language' parameter to specify the language (optional).
2725
// Defaults to 'en' if no valid language code is provided.
2826
const profanity = new ProfanityEngine({ language: 'es' });
29-
3027
```
3128

3229
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.
3330

34-
3531
## API Functions
3632

3733
### 1. `all()`
@@ -51,12 +47,23 @@ const searchWord = profanity.search('shit');
5147
// Returns true if the word is profane, otherwise false.
5248
```
5349

54-
### 3. Handling Empty Strings
50+
### 3. hasCurseWords(sentence)
51+
52+
Checks if a given sentence contains any profanity words.
53+
54+
```javascript
55+
const sentence = 'Do not use bad words like mierda or idiota.';
56+
const hasCurseWords = profanity.hasCurseWords(sentence);
57+
// Returns true if the sentence contains profanity words, otherwise false.
58+
```
59+
60+
### 4. Handling Empty Strings
5561

56-
The `search` function will return `false` for any empty string.
62+
The `search` and `hasCurseWords` functions will return false for any empty string.
5763

5864
```javascript
5965
const searchWord = profanity.search('');
66+
const hasCurseWords = profanity.hasCurseWords('');
6067
// Returns false for an empty string.
6168
```
6269

__tests__/engine.test.js

Lines changed: 7 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -3,22 +3,21 @@ import { ProfanityEngine } from '../index.js';
33
const language = process.env.LANGUAGE || 'en'; // Default to 'en' if the LANGUAGE environment variable is not set
44
let profanity;
55

6-
76
describe('ProfanityEngine Functions tests', () => {
87
beforeAll(async () => {
9-
profanity = new ProfanityEngine({
10-
language: 'en',
11-
testMode:true
12-
});
13-
await profanity.initialize(); // Initialize the profanity instance with the English language
14-
});
8+
profanity = new ProfanityEngine({
9+
language: 'en',
10+
testMode: true,
11+
});
12+
await profanity.initialize(); // Initialize the profanity instance with the English language
13+
});
1514

1615
it('Should get the correct language file path', async () => {
1716
const filePath = await profanity.getLanguageFilePath('es');
1817
expect(filePath).toContain('es.txt');
1918
});
2019

21-
it('Should return the default language file path for unknown language',async () => {
20+
it('Should return the default language file path for unknown language', async () => {
2221
const filePath = await profanity.getLanguageFilePath('fr');
2322
expect(filePath).toContain('en.txt');
2423
});

__tests__/english.test.js

Lines changed: 22 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -5,14 +5,14 @@ let profanity;
55

66
describe('English Profanity tests', () => {
77
beforeAll(async () => {
8-
profanity = new ProfanityEngine({
9-
language: 'en',
10-
testMode:true
11-
});
12-
await profanity.initialize(); // Initialize the profanity instance with the English language
13-
});
14-
15-
it('Should get all the profanity words in an array',async () => {
8+
profanity = new ProfanityEngine({
9+
language: 'en',
10+
testMode: true,
11+
});
12+
await profanity.initialize(); // Initialize the profanity instance with the English language
13+
});
14+
15+
it('Should get all the profanity words in an array', async () => {
1616
const allWords = await profanity.all();
1717
expect(allWords.length).toEqual(959);
1818
});
@@ -22,13 +22,25 @@ describe('English Profanity tests', () => {
2222
expect(searchWord).toEqual(true);
2323
});
2424

25-
it('Should return false for normal words', async() => {
25+
it('Should return false for normal words', async () => {
2626
const searchWord = await profanity.search('ka');
2727
expect(searchWord).toEqual(false);
2828
});
2929

30-
it('Should return false for any empty string',async () => {
30+
it('Should return false for any empty string', async () => {
3131
const searchWord = await profanity.search('');
3232
expect(searchWord).toEqual(true);
3333
});
34+
35+
it('Should return true for a sentence containing a profanity word', async () => {
36+
const sentence = 'Do not use bad words like shit or asshole.';
37+
const hasCurseWords = await profanity.hasCurseWords(sentence);
38+
expect(hasCurseWords).toEqual(true);
39+
});
40+
41+
it('Should return false for a sentence with no profanity word', async () => {
42+
const sentence = 'This is a clean and polite sentence.';
43+
const hasCurseWords = await profanity.hasCurseWords(sentence);
44+
expect(hasCurseWords).toEqual(false);
45+
});
3446
});

__tests__/spanish.test.js

Lines changed: 21 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -5,29 +5,41 @@ let profanity;
55

66
describe('Spanish Profanity tests', () => {
77
beforeAll(async () => {
8-
profanity = new ProfanityEngine({
9-
language: 'es',
10-
testMode:true
11-
});
12-
await profanity.initialize(); // Initialize the profanity instance with the English language
13-
});
8+
profanity = new ProfanityEngine({
9+
language: 'es',
10+
testMode: true,
11+
});
12+
await profanity.initialize(); // Initialize the profanity instance with the English language
13+
});
1414
it('Should get all the profanity words in an array', async () => {
1515
const allWords = await profanity.all();
1616
expect(allWords.length).toEqual(565);
1717
});
1818

19-
it('Should return true for profanity words',async () => {
19+
it('Should return true for profanity words', async () => {
2020
const searchWord = await profanity.search('labios');
2121
expect(searchWord).toEqual(true);
2222
});
2323

24-
it('Should return false for normal words', async() => {
24+
it('Should return false for normal words', async () => {
2525
const searchWord = await profanity.search('ka');
2626
expect(searchWord).toEqual(false);
2727
});
2828

29-
it('Should return false for any empty string',async () => {
29+
it('Should return false for any empty string', async () => {
3030
const searchWord = await profanity.search('');
3131
expect(searchWord).toEqual(true);
3232
});
33+
34+
it('Should return true for a sentence containing a profanity word', async () => {
35+
const sentence = 'No deberías decir malas culo palabras como mierda.';
36+
const hasCurseWords = await profanity.hasCurseWords(sentence);
37+
expect(hasCurseWords).toEqual(true);
38+
});
39+
40+
it('Should return false for a sentence with no profanity word', async () => {
41+
const sentence = 'Esta es una oración limpia y educada.';
42+
const hasCurseWords = await profanity.hasCurseWords(sentence);
43+
expect(hasCurseWords).toEqual(false);
44+
});
3345
});

index.js

Lines changed: 30 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,13 @@
1-
import { readFile } from "fs/promises";
2-
import path from "path";
3-
import { fileURLToPath } from "url";
1+
import { readFile } from 'fs/promises';
2+
import path from 'path';
3+
import { fileURLToPath } from 'url';
44

55
export class ProfanityEngine {
66
constructor(config) {
77
this.isTestMode = config && config.testMode ? config.testMode : false;
8-
this.language = config && config.language ? config.language : "en";
8+
this.language = config && config.language ? config.language : 'en';
99
this.terms = [];
10-
this.filePath = "";
10+
this.filePath = '';
1111
}
1212

1313
async initialize() {
@@ -18,24 +18,24 @@ export class ProfanityEngine {
1818
} catch (err) {
1919
if (this.isTestMode === false) {
2020
let message = `Error reading file: ${err.message}`;
21-
console.warn("Profanity words issue:", message);
21+
console.warn('Profanity words issue:', message);
2222
}
2323
this.terms = [];
2424
}
2525
}
2626

2727
async getLanguageFilePath(language) {
2828
const currentFilePath = fileURLToPath(import.meta.url);
29-
const dataFolderPath = path.join(path.dirname(currentFilePath), "data");
29+
const dataFolderPath = path.join(path.dirname(currentFilePath), 'data');
3030
const languageFilePath = path.join(dataFolderPath, `${language}.txt`);
3131
const fileExists = await this.fileExists(languageFilePath);
3232

3333
if (!fileExists) {
3434
if (this.isTestMode === false) {
3535
let message = `Warning: The ${language} language file could not be found. Defaulting to 'en' language.`;
36-
console.warn("Profanity words issue:", message);
36+
console.warn('Profanity words issue:', message);
3737
}
38-
return path.join(dataFolderPath, "en.txt");
38+
return path.join(dataFolderPath, 'en.txt');
3939
}
4040

4141
return languageFilePath;
@@ -52,16 +52,34 @@ export class ProfanityEngine {
5252

5353
async readFileAndSplit(filePath) {
5454
try {
55-
const fileContent = await readFile(filePath, "utf8");
56-
return fileContent.split("\n");
55+
const fileContent = await readFile(filePath, 'utf8');
56+
return fileContent.split('\n');
5757
} catch (err) {
5858
if (this.isTestMode === false) {
59-
console.warn("Profanity words issue:", err);
59+
console.warn('Profanity words issue:', err);
6060
}
6161
return [];
6262
}
6363
}
6464

65+
async hasCurseWords(sentence) {
66+
if (this.terms.length === 0) {
67+
await this.initialize();
68+
}
69+
70+
const wordsInSentence = sentence.split(/\s+/);
71+
const lowerCasedTerms = this.terms.map((term) => term.toLowerCase());
72+
73+
for (const word of wordsInSentence) {
74+
const lowerCasedWord = word.toLowerCase();
75+
if (lowerCasedTerms.includes(lowerCasedWord)) {
76+
return true;
77+
}
78+
}
79+
80+
return false;
81+
}
82+
6583
async all() {
6684
if (this.terms.length === 0) {
6785
await this.initialize();

package-lock.json

Lines changed: 25 additions & 3 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,11 @@
11
{
22
"name": "@coffeeandfun/google-profanity-words",
3-
"version": "2.0.0",
3+
"version": "2.1.0",
44
"description": "Full list of bad words and top swear words banned by Google.",
55
"main": "index.js",
66
"type": "module",
77
"scripts": {
8+
"format": "npx prettier . --write",
89
"test": "NODE_OPTIONS=--experimental-vm-modules NODE_NO_WARNINGS=1 jest",
910
"en": "NODE_OPTIONS=--experimental-vm-modules NODE_NO_WARNINGS=1 jest english.test.js",
1011
"es": "NODE_OPTIONS=--experimental-vm-modules NODE_NO_WARNINGS=1 jest spanish.test.js",
@@ -28,7 +29,7 @@
2829
},
2930
"homepage": "https://github.com/coffee-and-fun/google-profanity-words#readme",
3031
"devDependencies": {
31-
"jest": "^27.4.5"
32-
},
33-
"dependencies": {}
32+
"jest": "^27.4.5",
33+
"prettier": "3.0.0"
34+
}
3435
}

0 commit comments

Comments
 (0)