Skip to content

Commit

Permalink
Update: added ignoreExpressions option to max-classes-per-file (#15000)
Browse files Browse the repository at this point in the history
* Update: added ignoreExpressions option to max-classes-per-file

* Apply suggestions from code review

Co-authored-by: Nicholas C. Zakas <nicholas@humanwhocodes.com>

* Missed a spot

Co-authored-by: Nicholas C. Zakas <nicholas@humanwhocodes.com>
  • Loading branch information
JoshuaKGoldberg and nzakas committed Sep 4, 2021
1 parent e9764f3 commit dd10937
Show file tree
Hide file tree
Showing 3 changed files with 109 additions and 10 deletions.
35 changes: 32 additions & 3 deletions docs/rules/max-classes-per-file.md
Expand Up @@ -28,8 +28,12 @@ class Foo {}

## Options

This rule has a numeric option (defaulted to 1) to specify the
maximum number of classes.
This rule may be configured with either an object or a number.

If the option is an object, it may contain one or both of:

- `ignoreExpressions`: a boolean option (defaulted to `false`) to ignore class expressions.
- `max`: a numeric option (defaulted to 1) to specify the maximum number of classes.

For example:

Expand All @@ -39,11 +43,36 @@ For example:
}
```

Examples of **correct** code for this rule with the numeric option set to `2`:
```json
{
"max-classes-per-file": [
"error",
{ "ignoreExpressions": true, "max": 2 }
]
}
```

Examples of **correct** code for this rule with the `max` option set to `2`:

```js
/* eslint max-classes-per-file: ["error", 2] */

class Foo {}
class Bar {}
```

Examples of **correct** code for this rule with the `ignoreExpressions` option set to `true`:

```js
/* eslint max-classes-per-file: ["error", { ignoreExpressions: true }] */

class VisitorFactory {
forDescriptor(descriptor) {
return class {
visit(node) {
return `Visiting ${descriptor}.`;
}
};
}
}
```
38 changes: 31 additions & 7 deletions lib/rules/max-classes-per-file.js
Expand Up @@ -25,8 +25,25 @@ module.exports = {

schema: [
{
type: "integer",
minimum: 1
oneOf: [
{
type: "integer",
minimum: 1
},
{
type: "object",
properties: {
ignoreExpressions: {
type: "boolean"
},
max: {
type: "integer",
minimum: 1
}
},
additionalProperties: false
}
]
}
],

Expand All @@ -35,8 +52,10 @@ module.exports = {
}
},
create(context) {

const maxClasses = context.options[0] || 1;
const [option = {}] = context.options;
const [ignoreExpressions, max] = typeof option === "number"
? [false, option || 1]
: [option.ignoreExpressions, option.max || 1];

let classCount = 0;

Expand All @@ -45,19 +64,24 @@ module.exports = {
classCount = 0;
},
"Program:exit"(node) {
if (classCount > maxClasses) {
if (classCount > max) {
context.report({
node,
messageId: "maximumExceeded",
data: {
classCount,
max: maxClasses
max
}
});
}
},
"ClassDeclaration, ClassExpression"() {
"ClassDeclaration"() {
classCount++;
},
"ClassExpression"() {
if (!ignoreExpressions) {
classCount++;
}
}
};
}
Expand Down
46 changes: 46 additions & 0 deletions tests/lib/rules/max-classes-per-file.js
Expand Up @@ -29,6 +29,29 @@ ruleTester.run("max-classes-per-file", rule, {
{
code: "class Foo {}\nclass Bar {}",
options: [2]
},
{
code: "class Foo {}",
options: [{ max: 1 }]
},
{
code: "class Foo {}\nclass Bar {}",
options: [{ max: 2 }]
},
{
code: `
class Foo {}
const myExpression = class {}
`,
options: [{ ignoreExpressions: true, max: 1 }]
},
{
code: `
class Foo {}
class Bar {}
const myExpression = class {}
`,
options: [{ ignoreExpressions: true, max: 2 }]
}
],

Expand All @@ -37,6 +60,10 @@ ruleTester.run("max-classes-per-file", rule, {
code: "class Foo {}\nclass Bar {}",
errors: [{ messageId: "maximumExceeded", type: "Program" }]
},
{
code: "class Foo {}\nconst myExpression = class {}",
errors: [{ messageId: "maximumExceeded", type: "Program" }]
},
{
code: "var x = class {};\nvar y = class {};",
errors: [{ messageId: "maximumExceeded", type: "Program" }]
Expand All @@ -54,6 +81,25 @@ ruleTester.run("max-classes-per-file", rule, {
code: "class Foo {} class Bar {} class Baz {}",
options: [2],
errors: [{ messageId: "maximumExceeded", type: "Program" }]
},
{
code: `
class Foo {}
class Bar {}
const myExpression = class {}
`,
options: [{ ignoreExpressions: true, max: 1 }],
errors: [{ messageId: "maximumExceeded", type: "Program" }]
},
{
code: `
class Foo {}
class Bar {}
class Baz {}
const myExpression = class {}
`,
options: [{ ignoreExpressions: true, max: 2 }],
errors: [{ messageId: "maximumExceeded", type: "Program" }]
}
]
});

0 comments on commit dd10937

Please sign in to comment.