Skip to content

Commit b3b3938

Browse files
authored
Merge pull request #19228 from Yoast/PC-247-target-phrases-based-on-function-words-participles-and-or-punctuation-marks
PC-247 Target non-inclusive phrases with rules based on function words, participles, and/or punctuation marks
2 parents 8a9cc5b + a03b672 commit b3b3938

24 files changed

Lines changed: 806 additions & 74 deletions

packages/yoastseo/spec/languageProcessing/helpers/word/getWordsSpec.js

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,24 @@ describe( "a test for getting words from a sentence", function() {
4848
] );
4949
} );
5050

51+
it( "doesn't remove punctuation when doRemovePunctuation is false.", () => {
52+
const text = "A sentence with words. And some; punctuation.";
53+
const words = getWords( text, false );
54+
55+
expect( words ).toEqual( [
56+
"A",
57+
"sentence",
58+
"with",
59+
"words",
60+
".",
61+
"And",
62+
"some",
63+
";",
64+
"punctuation",
65+
".",
66+
] );
67+
} );
68+
5169
it( "doesn't return non-breaking space   in the result", () => {
5270
const text = "<p>Sri Tandjung noted that Javanese had been eating cooked (native black) soybeans since the 12th&nbsp;century.</p>\n";
5371

packages/yoastseo/spec/scoring/assessments/inclusiveLanguage/configuration/ageAssessmentsSpec.js

Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -82,4 +82,70 @@ describe( "Age assessments", function() {
8282
expect( isApplicable ).toBeFalsy();
8383
expect( assessor.getMarks() ).toEqual( [] );
8484
} );
85+
86+
it( "correctly identifies a phrase that is only recognized when followed by participle or simple past tense", () => {
87+
const mockPaper = new Paper( "The aged worked, the better they are." );
88+
const mockResearcher = Factory.buildMockResearcher( [ "The aged worked, the better they are." ] );
89+
const assessor = new InclusiveLanguageAssessment( ageAssessments.find( obj => obj.identifier === "theAged" ) );
90+
const isApplicable = assessor.isApplicable( mockPaper, mockResearcher );
91+
const assessmentResult = assessor.getResult();
92+
93+
expect( isApplicable ).toBeTruthy();
94+
expect( assessmentResult.getScore() ).toEqual( 3 );
95+
expect( assessmentResult.getText() ).toEqual(
96+
"Avoid using <i>the aged</i> as it is potentially harmful. Consider using an alternative, such as <i>older people</i>. " +
97+
"Or, if possible, be specific about the group you are referring to (e.g. <i>people older than 70</i>). " +
98+
"<a href='https://yoa.st/inclusive-language-age' target='_blank'>Learn more.</a>" );
99+
expect( assessmentResult.hasMarks() ).toBeTruthy();
100+
expect( assessor.getMarks() ).toEqual( [ new Mark( {
101+
original: "The aged worked, the better they are.",
102+
marked: "<yoastmark class='yoast-text-mark'>The aged worked, the better they are.</yoastmark>",
103+
} ) ] );
104+
} );
105+
it( "correctly identifies a phrase that is only recognized when followed by a function word", () => {
106+
const mockPaper = new Paper( "The aged however, did not go to the zoo." );
107+
const mockResearcher = Factory.buildMockResearcher( [ "The aged however, did not go to the zoo." ] );
108+
const assessor = new InclusiveLanguageAssessment( ageAssessments.find( obj => obj.identifier === "theAged" ) );
109+
const isApplicable = assessor.isApplicable( mockPaper, mockResearcher );
110+
const assessmentResult = assessor.getResult();
111+
112+
expect( isApplicable ).toBeTruthy();
113+
expect( assessmentResult.getScore() ).toEqual( 3 );
114+
expect( assessmentResult.getText() ).toEqual(
115+
"Avoid using <i>the aged</i> as it is potentially harmful. Consider using an alternative, such as <i>older people</i>. " +
116+
"Or, if possible, be specific about the group you are referring to (e.g. <i>people older than 70</i>). " +
117+
"<a href='https://yoa.st/inclusive-language-age' target='_blank'>Learn more.</a>" );
118+
expect( assessmentResult.hasMarks() ).toBeTruthy();
119+
expect( assessor.getMarks() ).toEqual( [ new Mark( {
120+
original: "The aged however, did not go to the zoo.",
121+
marked: "<yoastmark class='yoast-text-mark'>The aged however, did not go to the zoo.</yoastmark>",
122+
} ) ] );
123+
} );
124+
it( "correctly identifies a phrase that is only recognized when followed by a punctuation mark", () => {
125+
const mockPaper = new Paper( "I have always loved the aged!" );
126+
const mockResearcher = Factory.buildMockResearcher( [ "I have always loved the aged!" ] );
127+
const assessor = new InclusiveLanguageAssessment( ageAssessments.find( obj => obj.identifier === "theAged" ) );
128+
const isApplicable = assessor.isApplicable( mockPaper, mockResearcher );
129+
const assessmentResult = assessor.getResult();
130+
131+
expect( isApplicable ).toBeTruthy();
132+
expect( assessmentResult.getScore() ).toEqual( 3 );
133+
expect( assessmentResult.getText() ).toEqual(
134+
"Avoid using <i>the aged</i> as it is potentially harmful. Consider using an alternative, such as <i>older people</i>. " +
135+
"Or, if possible, be specific about the group you are referring to (e.g. <i>people older than 70</i>). " +
136+
"<a href='https://yoa.st/inclusive-language-age' target='_blank'>Learn more.</a>" );
137+
expect( assessmentResult.hasMarks() ).toBeTruthy();
138+
expect( assessor.getMarks() ).toEqual( [ new Mark( {
139+
original: "I have always loved the aged!",
140+
marked: "<yoastmark class='yoast-text-mark'>I have always loved the aged!</yoastmark>",
141+
} ) ] );
142+
} );
143+
it( "does not identify 'the aged' when not followed by punctuation, function word or participle", () => {
144+
const mockPaper = new Paper( "The aged cheese is the best." );
145+
const mockResearcher = Factory.buildMockResearcher( [ "The aged cheese is the best." ] );
146+
const assessor = new InclusiveLanguageAssessment( ageAssessments.find( obj => obj.identifier === "theAged" ) );
147+
const isApplicable = assessor.isApplicable( mockPaper, mockResearcher );
148+
149+
expect( isApplicable ).toBeFalsy();
150+
} );
85151
} );

packages/yoastseo/spec/scoring/assessments/inclusiveLanguage/configuration/appearanceAssessmentsSpec.js

Lines changed: 86 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ import Paper from "../../../../../src/values/Paper";
22
import EnglishResearcher from "../../../../../src/languageProcessing/languages/en/Researcher";
33
import InclusiveLanguageAssessment from "../../../../../src/scoring/assessments/inclusiveLanguage/InclusiveLanguageAssessment";
44
import assessments from "../../../../../src/scoring/assessments/inclusiveLanguage/configuration/appearanceAssessments";
5+
import Factory from "../../../../specHelpers/factory";
56
import Mark from "../../../../../src/values/Mark";
67

78
describe( "Appearance assessments", function() {
@@ -19,18 +20,19 @@ describe( "Appearance assessments", function() {
1920
expect( assessmentResult.getScore() ).toEqual( 6 );
2021
expect( assessmentResult.getText() ).toEqual(
2122
"Be careful when using <i>albinos</i> as it is potentially harmful. " +
22-
"Consider using an alternative, such as people with albinism, albino people, " +
23+
"Consider using an alternative, such as <i>people with albinism, albino people</i>, " +
2324
"unless referring to someone who explicitly wants to be referred to with this term. " +
2425
"<a href='https://yoa.st/inclusive-language-appearance' target='_blank'>Learn more.</a>" );
2526
expect( assessmentResult.hasMarks() ).toBeTruthy();
26-
expect( assessor.getMarks() ).toEqual( [ new Mark( {
27-
original: mockText,
28-
marked: "<yoastmark class='yoast-text-mark'>" + mockText + "</yoastmark>",
29-
} ) ] );
27+
expect( assessor.getMarks() ).toEqual( [ { _properties:
28+
{ marked: "<yoastmark class='yoast-text-mark'>This ad is aimed at albinos</yoastmark>",
29+
original: "This ad is aimed at albinos",
30+
fieldsToMark: [],
31+
} } ] );
3032
} );
3133

3234
it( "should target potentially non-inclusive phrases", function() {
33-
const mockText = "This ad is aimed at obese citizens";
35+
const mockText = "This ad is aimed at obese citizens.";
3436
const mockPaper = new Paper( mockText );
3537
const mockResearcher = new EnglishResearcher( mockPaper );
3638
const assessor = new InclusiveLanguageAssessment( assessments.find( obj => obj.identifier === "obese" ) );
@@ -47,25 +49,29 @@ describe( "Appearance assessments", function() {
4749
"Alternatively, if talking about a specific person, use their preferred descriptor if known. " +
4850
"<a href='https://yoa.st/inclusive-language-appearance' target='_blank'>Learn more.</a>" );
4951
expect( assessmentResult.hasMarks() ).toBeTruthy();
50-
expect( assessor.getMarks() ).toEqual( [ new Mark( {
51-
original: mockText,
52-
marked: "<yoastmark class='yoast-text-mark'>" + mockText + "</yoastmark>",
53-
} ) ] );
52+
expect( assessor.getMarks() ).toEqual( [
53+
{ _properties: {
54+
marked: "<yoastmark class='yoast-text-mark'>This ad is aimed at obese citizens.</yoastmark>",
55+
original: "This ad is aimed at obese citizens.",
56+
fieldsToMark: [],
57+
} } ] );
5458
} );
5559

5660
it( "should not target phrases preceded by certain words", function() {
57-
const mockText = "This ad is aimed at vertically challenged people";
61+
const mockText = "This ad is aimed at vertically challenged people.";
5862
const mockPaper = new Paper( mockText );
5963
const mockResearcher = new EnglishResearcher( mockPaper );
6064
const assessor = new InclusiveLanguageAssessment( assessments.find( obj => obj.identifier === "verticallyChallenged" ) );
6165

6266
const isApplicable = assessor.isApplicable( mockPaper, mockResearcher );
6367

6468
expect( isApplicable ).toBeTruthy();
65-
expect( assessor.getMarks() ).toEqual( [ new Mark( {
66-
original: mockText,
67-
marked: "<yoastmark class='yoast-text-mark'>" + mockText + "</yoastmark>",
68-
} ) ] );
69+
expect( assessor.getMarks() ).toEqual( [
70+
{ _properties: {
71+
marked: "<yoastmark class='yoast-text-mark'>This ad is aimed at vertically challenged people.</yoastmark>",
72+
original: "This ad is aimed at vertically challenged people.",
73+
fieldsToMark: [],
74+
} } ] );
6975
} );
7076

7177
it( "should not target phrases followed by by certain words", function() {
@@ -89,4 +95,69 @@ describe( "Appearance assessments", function() {
8995
expect( isApplicable ).toBeFalsy();
9096
expect( assessor.getMarks() ).toEqual( [] );
9197
} );
98+
it( "correctly identifies 'an albino' which is only recognized when followed by participle or simple past tense", () => {
99+
const mockPaper = new Paper( "An albino worked, the better they are." );
100+
const mockResearcher = Factory.buildMockResearcher( [ "An albino worked, the better they are." ] );
101+
const assessor = new InclusiveLanguageAssessment( assessments.find( obj => obj.identifier === "anAlbino" ) );
102+
const isApplicable = assessor.isApplicable( mockPaper, mockResearcher );
103+
const assessmentResult = assessor.getResult();
104+
105+
expect( isApplicable ).toBeTruthy();
106+
expect( assessmentResult.getScore() ).toEqual( 3 );
107+
expect( assessmentResult.getText() ).toEqual(
108+
"Be careful when using <i>an albino</i> as it is potentially harmful. Consider using an alternative, such as " +
109+
"<i>people with albinism, albino people</i>, unless referring to someone who explicitly wants to be referred to with this term. " +
110+
"<a href='https://yoa.st/inclusive-language-appearance' target='_blank'>Learn more.</a>" );
111+
expect( assessmentResult.hasMarks() ).toBeTruthy();
112+
expect( assessor.getMarks() ).toEqual( [ new Mark( {
113+
original: "An albino worked, the better they are.",
114+
marked: "<yoastmark class='yoast-text-mark'>An albino worked, the better they are.</yoastmark>",
115+
} ) ] );
116+
} );
117+
it( "correctly identifies 'an albino', which is only recognized when followed by a function word", () => {
118+
const mockPaper = new Paper( "An albino however, did not go to the zoo." );
119+
const mockResearcher = Factory.buildMockResearcher( [ "An albino however, did not go to the zoo." ] );
120+
const assessor = new InclusiveLanguageAssessment( assessments.find( obj => obj.identifier === "anAlbino" ) );
121+
const isApplicable = assessor.isApplicable( mockPaper, mockResearcher );
122+
const assessmentResult = assessor.getResult();
123+
124+
expect( isApplicable ).toBeTruthy();
125+
expect( assessmentResult.getScore() ).toEqual( 3 );
126+
expect( assessmentResult.getText() ).toEqual(
127+
"Be careful when using <i>an albino</i> as it is potentially harmful. Consider using an alternative, such as " +
128+
"<i>people with albinism, albino people</i>, unless referring to someone who explicitly wants to be referred to with this term. " +
129+
"<a href='https://yoa.st/inclusive-language-appearance' target='_blank'>Learn more.</a>" );
130+
expect( assessmentResult.hasMarks() ).toBeTruthy();
131+
expect( assessor.getMarks() ).toEqual( [ new Mark( {
132+
original: "An albino however, did not go to the zoo.",
133+
marked: "<yoastmark class='yoast-text-mark'>An albino however, did not go to the zoo.</yoastmark>",
134+
} ) ] );
135+
} );
136+
it( "correctly identifies 'an albino', which is only recognized when followed by a punctuation mark", () => {
137+
const mockPaper = new Paper( "I have always loved an albino!" );
138+
const mockResearcher = Factory.buildMockResearcher( [ "I have always loved an albino!" ] );
139+
const assessor = new InclusiveLanguageAssessment( assessments.find( obj => obj.identifier === "anAlbino" ) );
140+
const isApplicable = assessor.isApplicable( mockPaper, mockResearcher );
141+
const assessmentResult = assessor.getResult();
142+
143+
expect( isApplicable ).toBeTruthy();
144+
expect( assessmentResult.getScore() ).toEqual( 3 );
145+
expect( assessmentResult.getText() ).toEqual(
146+
"Be careful when using <i>an albino</i> as it is potentially harmful. Consider using an alternative, such as " +
147+
"<i>people with albinism, albino people</i>, unless referring to someone who explicitly wants to be referred to with this term. " +
148+
"<a href='https://yoa.st/inclusive-language-appearance' target='_blank'>Learn more.</a>" );
149+
expect( assessmentResult.hasMarks() ).toBeTruthy();
150+
expect( assessor.getMarks() ).toEqual( [ new Mark( {
151+
original: "I have always loved an albino!",
152+
marked: "<yoastmark class='yoast-text-mark'>I have always loved an albino!</yoastmark>",
153+
} ) ] );
154+
} );
155+
it( "does not identify 'an albino' when not followed by punctuation, function word or participle", () => {
156+
const mockPaper = new Paper( "An albino person walks on the street." );
157+
const mockResearcher = Factory.buildMockResearcher( [ "An albino person walks on the street." ] );
158+
const assessor = new InclusiveLanguageAssessment( assessments.find( obj => obj.identifier === "anAlbino" ) );
159+
const isApplicable = assessor.isApplicable( mockPaper, mockResearcher );
160+
161+
expect( isApplicable ).toBeFalsy();
162+
} );
92163
} );

packages/yoastseo/spec/scoring/assessments/inclusiveLanguage/configuration/disabilityAssessmentsSpec.js

Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -120,5 +120,71 @@ describe( "Disability assessments", function() {
120120

121121
expect( assessment.isApplicable( mockPaper, mockResearcher ) ).toBe( false );
122122
} );
123+
124+
it( "correctly identifies 'the disabled' which is only recognized when followed by participle or simple past tense", () => {
125+
const mockPaper = new Paper( "the disabled worked, the better they are." );
126+
const mockResearcher = Factory.buildMockResearcher( [ "The disabled worked, the better they are." ] );
127+
const assessor = new InclusiveLanguageAssessment( assessments.find( obj => obj.identifier === "theDisabled" ) );
128+
const isApplicable = assessor.isApplicable( mockPaper, mockResearcher );
129+
const assessmentResult = assessor.getResult();
130+
131+
expect( isApplicable ).toBeTruthy();
132+
expect( assessmentResult.getScore() ).toEqual( 3 );
133+
expect( assessmentResult.getText() ).toEqual(
134+
"Avoid using <i>the disabled</i> as it is potentially harmful. Consider using an alternative, such as " +
135+
"<i>people who have a disability</i>, <i>disabled people </i>. " +
136+
"<a href='https://yoa.st/inclusive-language-disability' target='_blank'>Learn more.</a>" );
137+
expect( assessmentResult.hasMarks() ).toBeTruthy();
138+
expect( assessor.getMarks() ).toEqual( [ new Mark( {
139+
original: "The disabled worked, the better they are.",
140+
marked: "<yoastmark class='yoast-text-mark'>The disabled worked, the better they are.</yoastmark>",
141+
} ) ] );
142+
} );
143+
it( "correctly identifies 'The disabled', which is only recognized when followed by a function word", () => {
144+
const mockPaper = new Paper( "The disabled however, did not go to the zoo." );
145+
const mockResearcher = Factory.buildMockResearcher( [ "The disabled however, did not go to the zoo." ] );
146+
const assessor = new InclusiveLanguageAssessment( assessments.find( obj => obj.identifier === "theDisabled" ) );
147+
const isApplicable = assessor.isApplicable( mockPaper, mockResearcher );
148+
const assessmentResult = assessor.getResult();
149+
150+
expect( isApplicable ).toBeTruthy();
151+
expect( assessmentResult.getScore() ).toEqual( 3 );
152+
expect( assessmentResult.getText() ).toEqual(
153+
"Avoid using <i>the disabled</i> as it is potentially harmful. Consider using an alternative, such as " +
154+
"<i>people who have a disability</i>, <i>disabled people </i>. " +
155+
"<a href='https://yoa.st/inclusive-language-disability' target='_blank'>Learn more.</a>" );
156+
expect( assessmentResult.hasMarks() ).toBeTruthy();
157+
expect( assessor.getMarks() ).toEqual( [ new Mark( {
158+
original: "The disabled however, did not go to the zoo.",
159+
marked: "<yoastmark class='yoast-text-mark'>The disabled however, did not go to the zoo.</yoastmark>",
160+
} ) ] );
161+
} );
162+
it( "correctly identifies 'The disabled', which is only recognized when followed by a punctuation mark", () => {
163+
const mockPaper = new Paper( "I have always loved the disabled!" );
164+
const mockResearcher = Factory.buildMockResearcher( [ "I have always loved the disabled!" ] );
165+
const assessor = new InclusiveLanguageAssessment( assessments.find( obj => obj.identifier === "theDisabled" ) );
166+
const isApplicable = assessor.isApplicable( mockPaper, mockResearcher );
167+
const assessmentResult = assessor.getResult();
168+
169+
expect( isApplicable ).toBeTruthy();
170+
expect( assessmentResult.getScore() ).toEqual( 3 );
171+
expect( assessmentResult.getText() ).toEqual(
172+
"Avoid using <i>the disabled</i> as it is potentially harmful. Consider using an alternative, such as " +
173+
"<i>people who have a disability</i>, <i>disabled people </i>. " +
174+
"<a href='https://yoa.st/inclusive-language-disability' target='_blank'>Learn more.</a>" );
175+
expect( assessmentResult.hasMarks() ).toBeTruthy();
176+
expect( assessor.getMarks() ).toEqual( [ new Mark( {
177+
original: "I have always loved the disabled!",
178+
marked: "<yoastmark class='yoast-text-mark'>I have always loved the disabled!</yoastmark>",
179+
} ) ] );
180+
} );
181+
it( "does not identify 'the disabled' when not followed by punctuation, function word or participle", () => {
182+
const mockPaper = new Paper( "The disabled person walks on the street." );
183+
const mockResearcher = Factory.buildMockResearcher( [ "The disabled person walks on the street." ] );
184+
const assessor = new InclusiveLanguageAssessment( assessments.find( obj => obj.identifier === "theDisabled" ) );
185+
const isApplicable = assessor.isApplicable( mockPaper, mockResearcher );
186+
187+
expect( isApplicable ).toBeFalsy();
188+
} );
123189
} );
124190

0 commit comments

Comments
 (0)