Skip to content

Commit

Permalink
Add create function to custom eslint rules, see phetsims/chipper#1451
Browse files Browse the repository at this point in the history
  • Loading branch information
samreid authored and zepumph committed Oct 22, 2024
1 parent 581a3b3 commit 8610f4c
Show file tree
Hide file tree
Showing 22 changed files with 916 additions and 874 deletions.
24 changes: 13 additions & 11 deletions eslint/rules/bad-chipper-text.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
// Copyright 2019, University of Colorado Boulder


/**
* Lint detector for invalid text in chipper
Expand All @@ -9,20 +9,22 @@
* @author Michael Kauzmann (PhET Interactive Simulations)
*/

module.exports = function( context ) {
const getBadTextTester = require( './getBadTextTester' );

const getBadTextTester = require( './getBadTextTester' );
module.exports = {
create: function( context ) {

// see getBadTextTester for schema.
const forbiddenTextObjects = [
// see getBadTextTester for schema.
const forbiddenTextObjects = [

// chipper should use perennial-alias instead of perennial, so that it can check out specific versions
'../perennial/js/'
];
// chipper should use perennial-alias instead of perennial, so that it can check out specific versions
'../perennial/js/'
];

return {
Program: getBadTextTester( 'bad-chipper-text', forbiddenTextObjects, context )
};
return {
Program: getBadTextTester( 'bad-chipper-text', forbiddenTextObjects, context )
};
}
};

module.exports.schema = [
Expand Down
28 changes: 15 additions & 13 deletions eslint/rules/bad-phet-library-text.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,23 +11,25 @@
* @author Michael Kauzmann (PhET Interactive Simulations)
*/

module.exports = function( context ) {
const getBadTextTester = require( './getBadTextTester' );

const getBadTextTester = require( './getBadTextTester' );
module.exports = {
create: function( context ) {

// see getBadTextTester for schema.
const forbiddenTextObjects = [
// see getBadTextTester for schema.
const forbiddenTextObjects = [

// accessing the sim as a global, like `phet.joist.sim` is a classic example of a hard dependency that can be a
// ticking time bomb for common code that isn't normally run outside phetsims (but could and may want to in the
// future). See https://github.com/phetsims/chipper/issues/1004
{ id: 'phet.joist', codeTokens: [ 'phet', '.', 'joist' ] },
'nopedy'
];
// accessing the sim as a global, like `phet.joist.sim` is a classic example of a hard dependency that can be a
// ticking time bomb for common code that isn't normally run outside phetsims (but could and may want to in the
// future). See https://github.com/phetsims/chipper/issues/1004
{ id: 'phet.joist', codeTokens: [ 'phet', '.', 'joist' ] },
'nopedy'
];

return {
Program: getBadTextTester( 'bad-phet-library-text', forbiddenTextObjects, context )
};
return {
Program: getBadTextTester( 'bad-phet-library-text', forbiddenTextObjects, context )
};
}
};

module.exports.schema = [
Expand Down
271 changes: 136 additions & 135 deletions eslint/rules/bad-sim-text.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,143 +9,144 @@
* @author Michael Kauzmann (PhET Interactive Simulations)
*/


module.exports = function( context ) {

const getBadTextTester = require( './getBadTextTester' );

// see getBadTextTester for schema.
const forbiddenTextObjects = [

// should be using phet.dot.Utils.roundSymmetric, Math.round does not treat positive and negative numbers
// symmetrically see https://github.com/phetsims/dot/issues/35#issuecomment-113587879
{ id: 'Math.round(', codeTokens: [ 'Math', '.', 'round', '(' ] },

// should be using `DOT/dotRandom`
{ id: 'Math.random()', codeTokens: [ 'Math', '.', 'random', '(', ')' ] },
{ id: '_.shuffle(', codeTokens: [ '_', '.', 'shuffle', '(' ] },
{ id: '_.sample(', codeTokens: [ '_', '.', 'sample', '(' ] },
{ id: '_.random(', codeTokens: [ '_', '.', 'random', '(' ] },
{ id: 'new Random()', codeTokens: [ 'new', 'Random', '(', ')' ] },

// You can use parseInt if you need a non base 10 radix
{ id: 'Number.parseInt(', codeTokens: [ 'Number', '.', 'parseInt', '(' ] },
{ id: 'Array.prototype.find', codeTokens: [ 'Array', '.', 'prototype', '.', 'find' ] },

// ParallelDOM.pdomOrder should not be mutated, instead only set with `setPDOMOrder`
'.pdomOrder.push(',

// Should import dotRandom instead of using the namespace
'phet.dot.dotRandom',

// Prefer using Pointer.isTouchLike() to help support Pen. This is not set in stone, please see
// https://github.com/phetsims/scenery/issues/1156 and feel free to discuss if there are usages you want to support.
' instanceof Touch ',

// Prevent accidental importing of files from the TypeScript build output directory
'chipper/dist',

// Relying on these in sim code can break PhET-iO playback, instead use Sim.dimensionProperty, see https://github.com/phetsims/joist/issues/768
'window.innerWidth',
'window.innerHeight',

// These are types that can be inferred by the common code and provided arguments
'new Enumeration<',
'new EnumerationProperty<',

// Voicing utterances should be registered with a Node for "voicing visibility", using Voicing.alertUtterance asserts
// that. See https://github.com/phetsims/scenery/issues/1403
'voicingUtteranceQueue.addToBack',

// Please use Text/RichText.STRING_PROPERTY_TANDEM_NAME when appropriate (though not all usages apply here, and
// you can ignore this rule), https://github.com/phetsims/scenery/issues/1451#issuecomment-1270576831
'\'stringProperty\'',

// Just pass these through, they work with structured cloning as is! See https://github.com/phetsims/tandem/issues/280
' NumberIO.toStateObject',
' NumberIO.fromStateObject',
' BooleanIO.toStateObject',
' BooleanIO.fromStateObject',
' StringIO.toStateObject',
' StringIO.fromStateObject',

'new Tandem(', // use createTandem(), never instantiate your own Tandem please

// Instead of using your own assertion, see and use Disposable.assertNotDisposable(), https://github.com/phetsims/axon/issues/436
'dispose is not supported, exists for the lifetime of the sim',

// In sims, don't allow setTimout and setInterval calls coming from window, see https://github.com/phetsims/phet-info/issues/59
{
id: 'setTimeout(',
regex: /(window\.| )setTimeout\(/
},
{
id: 'setInterval(',
regex: /(window\.| )setInterval\(/
},

// Decided on during developer meeting, in regards to https://github.com/phetsims/scenery/issues/1324, use `{ Type }`
// import syntax from SCENERY/imports.js
{
id: 'should import from SCENERY/imports.js instead of directly',
regex: /import.*from.*\/scenery\/(?!js\/imports.js)/
},

// Decided on during developer meeting, in regards to https://github.com/phetsims/scenery/issues/1324, use `{ Type }`
// import syntax from KITE/imports.js
{
id: 'should import from KITE/imports.js instead of directly',
regex: /import.*from.*\/kite\/(?!js\/imports.js)/
},

// See https://github.com/phetsims/tandem/issues/302. We don't want to duplicate this type everywhere. Also use 2
// spaces to prevent false positive for class fields like `public tandem: Tandem;` (which is fine).
{
id: 'Do not duplicate the definition of Tandem, instead use PickRequired<PhetioObjectOptions, \'tandem\'>',
regex: / {2}tandem\??: Tandem;/
},

// DOT/Utils.toFixed or DOT/Utils.toFixedNumber should be used instead of toFixed.
// JavaScript's toFixed is notoriously buggy. Behavior differs depending on browser,
// because the spec doesn't specify whether to round or floor.
{
id: '.toFixed(', // support regex with english names this way
regex: new RegExp( '(?<!Utils)\\.toFixed\\(' ) // NOTE: eslint parsing breaks when using regex syntax like `/regex/`
},

{
id: 'Import from statements require a *.js suffix',
predicate: line => {
if ( line.trim().indexOf( 'import ' ) === 0 && line.includes( ' from ' ) && ( !line.includes( '.js' ) && !line.includes( '.mjs' ) ) ) {
return false;
const getBadTextTester = require( './getBadTextTester' );

module.exports = {
create: function( context ) {

// see getBadTextTester for schema.
const forbiddenTextObjects = [

// should be using phet.dot.Utils.roundSymmetric, Math.round does not treat positive and negative numbers
// symmetrically see https://github.com/phetsims/dot/issues/35#issuecomment-113587879
{ id: 'Math.round(', codeTokens: [ 'Math', '.', 'round', '(' ] },

// should be using `DOT/dotRandom`
{ id: 'Math.random()', codeTokens: [ 'Math', '.', 'random', '(', ')' ] },
{ id: '_.shuffle(', codeTokens: [ '_', '.', 'shuffle', '(' ] },
{ id: '_.sample(', codeTokens: [ '_', '.', 'sample', '(' ] },
{ id: '_.random(', codeTokens: [ '_', '.', 'random', '(' ] },
{ id: 'new Random()', codeTokens: [ 'new', 'Random', '(', ')' ] },

// You can use parseInt if you need a non base 10 radix
{ id: 'Number.parseInt(', codeTokens: [ 'Number', '.', 'parseInt', '(' ] },
{ id: 'Array.prototype.find', codeTokens: [ 'Array', '.', 'prototype', '.', 'find' ] },

// ParallelDOM.pdomOrder should not be mutated, instead only set with `setPDOMOrder`
'.pdomOrder.push(',

// Should import dotRandom instead of using the namespace
'phet.dot.dotRandom',

// Prefer using Pointer.isTouchLike() to help support Pen. This is not set in stone, please see
// https://github.com/phetsims/scenery/issues/1156 and feel free to discuss if there are usages you want to support.
' instanceof Touch ',

// Prevent accidental importing of files from the TypeScript build output directory
'chipper/dist',

// Relying on these in sim code can break PhET-iO playback, instead use Sim.dimensionProperty, see https://github.com/phetsims/joist/issues/768
'window.innerWidth',
'window.innerHeight',

// These are types that can be inferred by the common code and provided arguments
'new Enumeration<',
'new EnumerationProperty<',

// Voicing utterances should be registered with a Node for "voicing visibility", using Voicing.alertUtterance asserts
// that. See https://github.com/phetsims/scenery/issues/1403
'voicingUtteranceQueue.addToBack',

// Please use Text/RichText.STRING_PROPERTY_TANDEM_NAME when appropriate (though not all usages apply here, and
// you can ignore this rule), https://github.com/phetsims/scenery/issues/1451#issuecomment-1270576831
'\'stringProperty\'',

// Just pass these through, they work with structured cloning as is! See https://github.com/phetsims/tandem/issues/280
' NumberIO.toStateObject',
' NumberIO.fromStateObject',
' BooleanIO.toStateObject',
' BooleanIO.fromStateObject',
' StringIO.toStateObject',
' StringIO.fromStateObject',

'new Tandem(', // use createTandem(), never instantiate your own Tandem please

// Instead of using your own assertion, see and use Disposable.assertNotDisposable(), https://github.com/phetsims/axon/issues/436
'dispose is not supported, exists for the lifetime of the sim',

// In sims, don't allow setTimout and setInterval calls coming from window, see https://github.com/phetsims/phet-info/issues/59
{
id: 'setTimeout(',
regex: /(window\.| )setTimeout\(/
},
{
id: 'setInterval(',
regex: /(window\.| )setInterval\(/
},

// Decided on during developer meeting, in regards to https://github.com/phetsims/scenery/issues/1324, use `{ Type }`
// import syntax from SCENERY/imports.js
{
id: 'should import from SCENERY/imports.js instead of directly',
regex: /import.*from.*\/scenery\/(?!js\/imports.js)/
},

// Decided on during developer meeting, in regards to https://github.com/phetsims/scenery/issues/1324, use `{ Type }`
// import syntax from KITE/imports.js
{
id: 'should import from KITE/imports.js instead of directly',
regex: /import.*from.*\/kite\/(?!js\/imports.js)/
},

// See https://github.com/phetsims/tandem/issues/302. We don't want to duplicate this type everywhere. Also use 2
// spaces to prevent false positive for class fields like `public tandem: Tandem;` (which is fine).
{
id: 'Do not duplicate the definition of Tandem, instead use PickRequired<PhetioObjectOptions, \'tandem\'>',
regex: / {2}tandem\??: Tandem;/
},

// DOT/Utils.toFixed or DOT/Utils.toFixedNumber should be used instead of toFixed.
// JavaScript's toFixed is notoriously buggy. Behavior differs depending on browser,
// because the spec doesn't specify whether to round or floor.
{
id: '.toFixed(', // support regex with english names this way
regex: new RegExp( '(?<!Utils)\\.toFixed\\(' ) // NOTE: eslint parsing breaks when using regex syntax like `/regex/`
},

{
id: 'Import from statements require a *.js suffix',
predicate: line => {
if ( line.trim().indexOf( 'import ' ) === 0 && line.includes( ' from ' ) && ( !line.includes( '.js' ) && !line.includes( '.mjs' ) ) ) {
return false;
}
return true;
}
return true;
}
},
{
id: 'Import statements require a *.js suffix',
predicate: line => {
if ( line.trim().indexOf( 'import \'' ) === 0 && line.indexOf( ';' ) >= 0 && line.indexOf( '.js' ) === -1 ) {
return false;
},
{
id: 'Import statements require a *.js suffix',
predicate: line => {
if ( line.trim().indexOf( 'import \'' ) === 0 && line.indexOf( ';' ) >= 0 && line.indexOf( '.js' ) === -1 ) {
return false;
}
return true;
}
return true;
}
},

{
id: 'Prefer "Standard PhET-iO Wrapper to "standard wrapper"',
regex: /[Ss][Tt][Aa][Nn][Dd][Aa][Rr][Dd][- _][Ww][Rr][Aa][Pp][Pp][Ee][Rr]/
},

// combo box is two words, moved to sim-specific bad text from the general one because of https://github.com/phetsims/website-meteor/issues/690
'combobox', // prefer combo box
'Combobox', // prefer Combo Box
'COMBOBOX' // prefer COMBO_BOX
];

return {
Program: getBadTextTester( 'bad-sim-text', forbiddenTextObjects, context )
};
},

{
id: 'Prefer "Standard PhET-iO Wrapper to "standard wrapper"',
regex: /[Ss][Tt][Aa][Nn][Dd][Aa][Rr][Dd][- _][Ww][Rr][Aa][Pp][Pp][Ee][Rr]/
},

// combo box is two words, moved to sim-specific bad text from the general one because of https://github.com/phetsims/website-meteor/issues/690
'combobox', // prefer combo box
'Combobox', // prefer Combo Box
'COMBOBOX' // prefer COMBO_BOX
];

return {
Program: getBadTextTester( 'bad-sim-text', forbiddenTextObjects, context )
};
}
};

module.exports.schema = [
Expand Down
Loading

0 comments on commit 8610f4c

Please sign in to comment.