Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Td/class syntax #21325

Draft
wants to merge 12 commits into
base: trunk
Choose a base branch
from
Prev Previous commit
Next Next commit
Uses class syntax for assessors (first pass)
  • Loading branch information
mhkuu committed Apr 18, 2024
commit 8b8e18ef248daa8924c04c701d87177f671adbb1
505 changes: 253 additions & 252 deletions packages/yoastseo/src/scoring/assessor.js

Large diffs are not rendered by default.

271 changes: 129 additions & 142 deletions packages/yoastseo/src/scoring/contentAssessor.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
import { inherits } from "util";

import { map, sum } from "lodash-es";
import Assessor from "./assessor.js";
import ParagraphTooLong from "./assessments/readability/ParagraphTooLongAssessment.js";
import SentenceLengthInText from "./assessments/readability/SentenceLengthInTextAssessment.js";
Expand All @@ -8,168 +7,156 @@ import TransitionWords from "./assessments/readability/TransitionWordsAssessment
import PassiveVoice from "./assessments/readability/PassiveVoiceAssessment.js";
import SentenceBeginnings from "./assessments/readability/SentenceBeginningsAssessment.js";
import TextPresence from "./assessments/readability/TextPresenceAssessment.js";

/*
Temporarily disabled:
var sentenceLengthInDescription = require( "./assessments/sentenceLengthInDescriptionAssessment.js" );
*/

import scoreToRating from "./interpreters/scoreToRating";

import { map, sum } from "lodash-es";

/**
* Creates the Assessor
*
* @param {object} researcher The researcher to use for the analysis.
* @param {Object} options The options for this assessor.
* @param {Object} options.marker The marker to pass the list of marks to.
*
* @constructor
*/
const ContentAssessor = function( researcher, options = {} ) {
Assessor.call( this, researcher, options );
this.type = "contentAssessor";
this._assessments = [
new SubheadingDistributionTooLong(),
new ParagraphTooLong(),
new SentenceLengthInText(),
new TransitionWords(),
new PassiveVoice(),
new TextPresence(),
new SentenceBeginnings(),
// Temporarily disabled: wordComplexity,
];
};

inherits( ContentAssessor, Assessor );

/**
* Calculates the weighted rating for languages that have all assessments based on a given rating.
*
* @param {number} rating The rating to be weighted.
* @returns {number} The weighted rating.
* The ContentAssessor class is used for the readability analysis.
*/
ContentAssessor.prototype.calculatePenaltyPointsFullSupport = function( rating ) {
switch ( rating ) {
case "bad":
return 3;
case "ok":
return 2;
default:
case "good":
return 0;
export default class ContentAssessor extends Assessor {
/**
* Creates a new ContentAssessor instance.
* @param {Researcher} researcher The researcher to use.
* @param {Object} [options] The assessor options.
*/
constructor( researcher, options ) {
super( researcher, options );
this.type = "contentAssessor";

this._assessments = [
new SubheadingDistributionTooLong(),
new ParagraphTooLong(),
new SentenceLengthInText(),
new TransitionWords(),
new PassiveVoice(),
new TextPresence(),
new SentenceBeginnings(),
];
}
};

/**
* Calculates the weighted rating for languages that don't have all assessments based on a given rating.
*
* @param {number} rating The rating to be weighted.
* @returns {number} The weighted rating.
*/
ContentAssessor.prototype.calculatePenaltyPointsPartialSupport = function( rating ) {
switch ( rating ) {
case "bad":
return 4;
case "ok":
return 2;
default:
case "good":
return 0;
/**
* Calculates the weighted rating for languages that have all assessments based on a given rating.
*
* @param {string} rating The rating to be weighted.
* @returns {number} The weighted rating.
*/
calculatePenaltyPointsFullSupport( rating ) {
switch ( rating ) {
case "bad":
return 3;
case "ok":
return 2;
default:
case "good":
return 0;
}
}
};

/**
* Determines whether a language is fully supported. If a language supports 8 content assessments
* it is fully supported
*
* @returns {boolean} True if fully supported.
*/
ContentAssessor.prototype._allAssessmentsSupported = function() {
const numberOfAssessments = this._assessments.length;
const applicableAssessments = this.getApplicableAssessments();
return applicableAssessments.length === numberOfAssessments;
};
/**
* Calculates the weighted rating for languages that don't have all assessments based on a given rating.
*
* @param {string} rating The rating to be weighted.
* @returns {number} The weighted rating.
*/
calculatePenaltyPointsPartialSupport( rating ) {
switch ( rating ) {
case "bad":
return 4;
case "ok":
return 2;
default:
case "good":
return 0;
}
}

/**
* Calculates the penalty points based on the assessment results.
*
* @returns {number} The total penalty points for the results.
*/
ContentAssessor.prototype.calculatePenaltyPoints = function() {
const results = this.getValidResults();
/**
* Determines whether a language is fully supported. If a language supports 8 content assessments
* it is fully supported
*
* @returns {boolean} True if fully supported.
*/
_allAssessmentsSupported() {
const numberOfAssessments = this._assessments.length;
const applicableAssessments = this.getApplicableAssessments();
return applicableAssessments.length === numberOfAssessments;
}

const penaltyPoints = map( results, function( result ) {
const rating = scoreToRating( result.getScore() );
/**
* Calculates the penalty points based on the assessment results.
*
* @returns {number} The total penalty points for the results.
*/
calculatePenaltyPoints() {
const results = this.getValidResults();

if ( this._allAssessmentsSupported() ) {
return this.calculatePenaltyPointsFullSupport( rating );
}
const penaltyPoints = map( results, function( result ) {
const rating = scoreToRating( result.getScore() );

return this.calculatePenaltyPointsPartialSupport( rating );
}.bind( this ) );
if ( this._allAssessmentsSupported() ) {
return this.calculatePenaltyPointsFullSupport( rating );
}

return sum( penaltyPoints );
};
return this.calculatePenaltyPointsPartialSupport( rating );
}.bind( this ) );

/**
* Rates the penalty points
*
* @param {number} totalPenaltyPoints The amount of penalty points.
* @returns {number} The score based on the amount of penalty points.
*
* @private
*/
ContentAssessor.prototype._ratePenaltyPoints = function( totalPenaltyPoints ) {
if ( this.getValidResults().length === 1 ) {
// If we have only 1 result, we only have a "no content" result
return 30;
return sum( penaltyPoints );
}

if ( this._allAssessmentsSupported() ) {
// Determine the total score based on the total penalty points.
if ( totalPenaltyPoints > 6 ) {
// A red indicator.
return 30;
}

if ( totalPenaltyPoints > 4 ) {
// An orange indicator.
return 60;
}
} else {
if ( totalPenaltyPoints > 4 ) {
// A red indicator.
/**
* Rates the penalty points
*
* @param {number} totalPenaltyPoints The amount of penalty points.
* @returns {number} The score based on the amount of penalty points.
*
* @private
*/
_ratePenaltyPoints( totalPenaltyPoints ) {
if ( this.getValidResults().length === 1 ) {
// If we have only 1 result, we only have a "no content" result
return 30;
}

if ( totalPenaltyPoints > 2 ) {
// An orange indicator.
return 60;
if ( this._allAssessmentsSupported() ) {
// Determine the total score based on the total penalty points.
if ( totalPenaltyPoints > 6 ) {
// A red indicator.
return 30;
}

if ( totalPenaltyPoints > 4 ) {
// An orange indicator.
return 60;
}
} else {
if ( totalPenaltyPoints > 4 ) {
// A red indicator.
return 30;
}

if ( totalPenaltyPoints > 2 ) {
// An orange indicator.
return 60;
}
}
// A green indicator.
return 90;
}
// A green indicator.
return 90;
};

/**
* Calculates the overall score based on the assessment results.
*
* @returns {number} The overall score.
*/
ContentAssessor.prototype.calculateOverallScore = function() {
const results = this.getValidResults();

// If you have no content, you have a red indicator.
if ( results.length === 0 ) {
return 30;
}
/**
* Calculates the overall score based on the assessment results.
*
* @returns {number} The overall score.
*/
calculateOverallScore() {
const results = this.getValidResults();

const totalPenaltyPoints = this.calculatePenaltyPoints();

return this._ratePenaltyPoints( totalPenaltyPoints );
};
// If you have no content, you have a red indicator.
if ( results.length === 0 ) {
return 30;
}

export default ContentAssessor;
const totalPenaltyPoints = this.calculatePenaltyPoints();

return this._ratePenaltyPoints( totalPenaltyPoints );
}
}
80 changes: 33 additions & 47 deletions packages/yoastseo/src/scoring/cornerstone/contentAssessor.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,3 @@
import { inherits } from "util";
import Assessor from "../assessor.js";
import ContentAssessor from "../contentAssessor";
import ParagraphTooLong from "../assessments/readability/ParagraphTooLongAssessment.js";
import SentenceLengthInText from "../assessments/readability/SentenceLengthInTextAssessment.js";
Expand All @@ -9,50 +7,38 @@ import PassiveVoice from "../assessments/readability/PassiveVoiceAssessment.js";
import SentenceBeginnings from "../assessments/readability/SentenceBeginningsAssessment.js";
import TextPresence from "../assessments/readability/TextPresenceAssessment.js";

/*
Temporarily disabled:

var sentenceLengthInDescription = require( "./assessments/readability/sentenceLengthInDescriptionAssessment.js" );
*/

/**
* Creates the Assessor
*
* @param {object} researcher The researcher used for the analysis.
* @param {Object} options The options for this assessor.
* @param {Object} options.marker The marker to pass the list of marks to.
*
* @constructor
* The CornerStoneContentAssessor class is used for the readability analysis on cornerstone content.
*/
const CornerStoneContentAssessor = function( researcher, options = {} ) {
Assessor.call( this, researcher, options );
this.type = "cornerstoneContentAssessor";

this._assessments = [
new SubheadingDistributionTooLong( {
parameters: {
slightlyTooMany: 250,
farTooMany: 300,
recommendedMaximumLength: 250,
},
applicableIfTextLongerThan: 250,
cornerstoneContent: true,
} ),
new ParagraphTooLong(),
new SentenceLengthInText( {
slightlyTooMany: 20,
farTooMany: 25,
}, true ),
new TransitionWords(),
new PassiveVoice(),
new TextPresence(),
new SentenceBeginnings(),
// Temporarily disabled: wordComplexity,
];
};

inherits( CornerStoneContentAssessor, ContentAssessor );


export default CornerStoneContentAssessor;

export default class CornerStoneContentAssessor extends ContentAssessor {
/**
* Creates a new CornerStoneContentAssessor instance.
* @param {Researcher} researcher The researcher to use.
* @param {Object} [options] The assessor options.
*/
constructor( researcher, options ) {
super( researcher, options );
this.type = "cornerstoneContentAssessor";

this._assessments = [
new SubheadingDistributionTooLong( {
parameters: {
slightlyTooMany: 250,
farTooMany: 300,
recommendedMaximumLength: 250,
},
applicableIfTextLongerThan: 250,
cornerstoneContent: true,
} ),
new ParagraphTooLong(),
new SentenceLengthInText( {
slightlyTooMany: 20,
farTooMany: 25,
}, true ),
new TransitionWords(),
new PassiveVoice(),
new TextPresence(),
new SentenceBeginnings(),
];
}
}