diff --git a/.eslintrc.js b/.eslintrc.js index 9bf4200c..02e2d701 100644 --- a/.eslintrc.js +++ b/.eslintrc.js @@ -18,6 +18,7 @@ module.exports = { 'global-require': 'off', 'no-bitwise': 'off', 'no-console': 'off', + 'func-names': 'off', 'no-continue': 'off', 'no-else-return': 'off', 'no-param-reassign': 'off', diff --git a/.gitignore b/.gitignore index 3614b26f..77dd2e5e 100644 --- a/.gitignore +++ b/.gitignore @@ -9,3 +9,4 @@ convertLib.sol antlr4.jar /docs/.sass-cache/ _temp/ +.solhint.json diff --git a/docs/rules.md b/docs/rules.md index 4868aab8..002284c7 100644 --- a/docs/rules.md +++ b/docs/rules.md @@ -12,10 +12,10 @@ title: "Rule Index of Solhint" | [function-max-lines](./rules/best-practises/function-max-lines.md) | Function body contains "count" lines but allowed no more than maxlines. | | | [max-line-length](./rules/best-practises/max-line-length.md) | Line length must be no more than maxlen. | | | [max-states-count](./rules/best-practises/max-states-count.md) | Contract has "some count" states declarations but allowed no more than maxstates. | ✔️ | -| [no-console](./rules/best-practises/no-console.md) | No console.log/logInt/logBytesX/logString/etc & No hardhat and forge-std console.sol import statements | ✔️ | +| [no-console](./rules/best-practises/no-console.md) | No console.log/logInt/logBytesX/logString/etc & No hardhat and forge-std console.sol import statements. | ✔️ | | [no-empty-blocks](./rules/best-practises/no-empty-blocks.md) | Code contains empty block. | ✔️ | -| [no-global-import](./rules/best-practises/no-global-import.md) | Import statement includes an entire file instead of selected symbols | ✔️ | -| [no-unused-import](./rules/best-practises/no-unused-import.md) | Imported name is not used | ✔️ | +| [no-global-import](./rules/best-practises/no-global-import.md) | Import statement includes an entire file instead of selected symbols. | ✔️ | +| [no-unused-import](./rules/best-practises/no-unused-import.md) | Imported name is not used. | ✔️ | | [no-unused-vars](./rules/best-practises/no-unused-vars.md) | Variable "name" is unused. | ✔️ | | [payable-fallback](./rules/best-practises/payable-fallback.md) | When fallback is not payable you will not be able to receive ethers. | ✔️ | | [reason-string](./rules/best-practises/reason-string.md) | Require or revert statement must have a reason string and check that each reason string is at most N characters long. | ✔️ | @@ -32,22 +32,23 @@ title: "Rule Index of Solhint" ## Style Guide Rules -| Rule Id | Error | Recommended | -| ------------------------------------------------------------------------------------ | -------------------------------------------------------------------------------------- | ----------- | -| [const-name-snakecase](./rules/naming/const-name-snakecase.md) | Constant name must be in capitalized SNAKE_CASE. | ✔️ | -| [contract-name-camelcase](./rules/naming/contract-name-camelcase.md) | Contract name must be in CamelCase. | ✔️ | -| [event-name-camelcase](./rules/naming/event-name-camelcase.md) | Event name must be in CamelCase. | ✔️ | -| [func-name-mixedcase](./rules/naming/func-name-mixedcase.md) | Function name must be in mixedCase. | ✔️ | -| [func-param-name-mixedcase](./rules/naming/func-param-name-mixedcase.md) | Function param name must be in mixedCase | | -| [modifier-name-mixedcase](./rules/naming/modifier-name-mixedcase.md) | Modifier name must be in mixedCase. | | -| [named-parameters-mapping](./rules/naming/named-parameters-mapping.md) | Solidity v0.8.18 introduced named parameters on the mappings definition | | -| [private-vars-leading-underscore](./rules/naming/private-vars-leading-underscore.md) | Private and internal names must start with a single underscore. | | -| [use-forbidden-name](./rules/naming/use-forbidden-name.md) | Avoid to use letters 'I', 'l', 'O' as identifiers. | ✔️ | -| [var-name-mixedcase](./rules/naming/var-name-mixedcase.md) | Variable name must be in mixedCase. | ✔️ | -| [func-order](./rules/order/func-order.md) | Function order is incorrect. | | -| [imports-on-top](./rules/order/imports-on-top.md) | Import statements must be on top. | ✔️ | -| [ordering](./rules/order/ordering.md) | Check order of elements in file and inside each contract, according to the style guide | | -| [visibility-modifier-order](./rules/order/visibility-modifier-order.md) | Visibility modifier must be first in list of modifiers. | ✔️ | +| Rule Id | Error | Recommended | +| ------------------------------------------------------------------------------------ | ------------------------------------------------------------------------------------------------------- | ----------- | +| [const-name-snakecase](./rules/naming/const-name-snakecase.md) | Constant name must be in capitalized SNAKE_CASE. (Does not check IMMUTABLES, use immutable-vars-naming) | ✔️ | +| [contract-name-camelcase](./rules/naming/contract-name-camelcase.md) | Contract name must be in CamelCase. | ✔️ | +| [event-name-camelcase](./rules/naming/event-name-camelcase.md) | Event name must be in CamelCase. | ✔️ | +| [func-name-mixedcase](./rules/naming/func-name-mixedcase.md) | Function name must be in mixedCase. | ✔️ | +| [func-param-name-mixedcase](./rules/naming/func-param-name-mixedcase.md) | Function param name must be in mixedCase. | | +| [immutable-vars-naming](./rules/naming/immutable-vars-naming.md) | Check Immutable variables. Capitalized SNAKE_CASE or mixedCase depending on configuration. | ✔️ | +| [modifier-name-mixedcase](./rules/naming/modifier-name-mixedcase.md) | Modifier name must be in mixedCase. | | +| [named-parameters-mapping](./rules/naming/named-parameters-mapping.md) | Solidity v0.8.18 introduced named parameters on the mappings definition. | | +| [private-vars-leading-underscore](./rules/naming/private-vars-leading-underscore.md) | Private and internal names must start with a single underscore. | | +| [use-forbidden-name](./rules/naming/use-forbidden-name.md) | Avoid to use letters 'I', 'l', 'O' as identifiers. | ✔️ | +| [var-name-mixedcase](./rules/naming/var-name-mixedcase.md) | Variable name must be in mixedCase. (Does not check IMMUTABLES, use immutable-vars-naming) | ✔️ | +| [func-order](./rules/order/func-order.md) | Function order is incorrect. | | +| [imports-on-top](./rules/order/imports-on-top.md) | Import statements must be on top. | ✔️ | +| [ordering](./rules/order/ordering.md) | Check order of elements in file and inside each contract, according to the style guide. | | +| [visibility-modifier-order](./rules/order/visibility-modifier-order.md) | Visibility modifier must be first in list of modifiers. | ✔️ | ## Security Rules diff --git a/docs/rules/best-practises/no-console.md b/docs/rules/best-practises/no-console.md index 6fc4cb3e..da6676ed 100644 --- a/docs/rules/best-practises/no-console.md +++ b/docs/rules/best-practises/no-console.md @@ -14,7 +14,7 @@ title: "no-console | Solhint" ## Description -No console.log/logInt/logBytesX/logString/etc & No hardhat and forge-std console.sol import statements +No console.log/logInt/logBytesX/logString/etc & No hardhat and forge-std console.sol import statements. ## Options This rule accepts a string option of rule severity. Must be one of "error", "warn", "off". Default to error. diff --git a/docs/rules/best-practises/no-global-import.md b/docs/rules/best-practises/no-global-import.md index dd16447e..1d95ccd4 100644 --- a/docs/rules/best-practises/no-global-import.md +++ b/docs/rules/best-practises/no-global-import.md @@ -12,7 +12,7 @@ title: "no-global-import | Solhint" ## Description -Import statement includes an entire file instead of selected symbols +Import statement includes an entire file instead of selected symbols. ## Options This rule accepts a string option of rule severity. Must be one of "error", "warn", "off". Default to warn. diff --git a/docs/rules/best-practises/no-unused-import.md b/docs/rules/best-practises/no-unused-import.md index e03199a1..5643b9fa 100644 --- a/docs/rules/best-practises/no-unused-import.md +++ b/docs/rules/best-practises/no-unused-import.md @@ -12,7 +12,7 @@ title: "no-unused-import | Solhint" ## Description -Imported name is not used +Imported name is not used. ## Options This rule accepts a string option of rule severity. Must be one of "error", "warn", "off". Default to warn. diff --git a/docs/rules/naming/const-name-snakecase.md b/docs/rules/naming/const-name-snakecase.md index 711bc563..fc5cb3ac 100644 --- a/docs/rules/naming/const-name-snakecase.md +++ b/docs/rules/naming/const-name-snakecase.md @@ -12,7 +12,7 @@ title: "const-name-snakecase | Solhint" ## Description -Constant name must be in capitalized SNAKE_CASE. +Constant name must be in capitalized SNAKE_CASE. (Does not check IMMUTABLES, use immutable-vars-naming) ## Options This rule accepts a string option of rule severity. Must be one of "error", "warn", "off". Default to warn. diff --git a/docs/rules/naming/func-param-name-mixedcase.md b/docs/rules/naming/func-param-name-mixedcase.md index b1f9397a..3ad19653 100644 --- a/docs/rules/naming/func-param-name-mixedcase.md +++ b/docs/rules/naming/func-param-name-mixedcase.md @@ -9,7 +9,7 @@ title: "func-param-name-mixedcase | Solhint" ![Default Severity Badge warn](https://img.shields.io/badge/Default%20Severity-warn-yellow) ## Description -Function param name must be in mixedCase +Function param name must be in mixedCase. ## Options This rule accepts a string option of rule severity. Must be one of "error", "warn", "off". Default to warn. diff --git a/docs/rules/naming/immutable-vars-naming.md b/docs/rules/naming/immutable-vars-naming.md new file mode 100644 index 00000000..8705d7ec --- /dev/null +++ b/docs/rules/naming/immutable-vars-naming.md @@ -0,0 +1,45 @@ +--- +warning: "This is a dynamically generated file. Do not edit manually." +layout: "default" +title: "immutable-vars-naming | Solhint" +--- + +# immutable-vars-naming +![Recommended Badge](https://img.shields.io/badge/-Recommended-brightgreen) +![Category Badge](https://img.shields.io/badge/-Style%20Guide%20Rules-informational) +![Default Severity Badge warn](https://img.shields.io/badge/Default%20Severity-warn-yellow) +> The {"extends": "solhint:recommended"} property in a configuration file enables this rule. + + +## Description +Check Immutable variables. Capitalized SNAKE_CASE or mixedCase depending on configuration. + +## Options +This rule accepts an array of options: + +| Index | Description | Default Value | +| ----- | ---------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------ | +| 0 | Rule severity. Must be one of "error", "warn", "off". | warn | +| 1 | A JSON object with a single property "immutablesAsConstants" as boolean specifying if immutable variables should be treated as constants | {"immutablesAsConstants":true} | + + +### Example Config +```json +{ + "rules": { + "immutable-vars-naming": ["warn",{"immutablesAsConstants":true}] + } +} +``` + + +## Examples +This rule does not have examples. + +## Version +This rule is introduced in the latest version. + +## Resources +- [Rule source](https://github.com/protofire/solhint/tree/master/lib/rules/naming/immutable-vars-naming.js) +- [Document source](https://github.com/protofire/solhint/tree/master/docs/rules/naming/immutable-vars-naming.md) +- [Test cases](https://github.com/protofire/solhint/tree/master/test/rules/naming/immutable-vars-naming.js) diff --git a/docs/rules/naming/named-parameters-mapping.md b/docs/rules/naming/named-parameters-mapping.md index f23c7a8e..6ae15579 100644 --- a/docs/rules/naming/named-parameters-mapping.md +++ b/docs/rules/naming/named-parameters-mapping.md @@ -9,7 +9,7 @@ title: "named-parameters-mapping | Solhint" ![Default Severity Badge off](https://img.shields.io/badge/Default%20Severity-off-undefined) ## Description -Solidity v0.8.18 introduced named parameters on the mappings definition +Solidity v0.8.18 introduced named parameters on the mappings definition. ## Options This rule accepts a string option of rule severity. Must be one of "error", "warn", "off". Default to off. diff --git a/docs/rules/naming/var-name-mixedcase.md b/docs/rules/naming/var-name-mixedcase.md index 824735fd..913a62cd 100644 --- a/docs/rules/naming/var-name-mixedcase.md +++ b/docs/rules/naming/var-name-mixedcase.md @@ -12,7 +12,7 @@ title: "var-name-mixedcase | Solhint" ## Description -Variable name must be in mixedCase. +Variable name must be in mixedCase. (Does not check IMMUTABLES, use immutable-vars-naming) ## Options This rule accepts a string option of rule severity. Must be one of "error", "warn", "off". Default to warn. diff --git a/docs/rules/order/ordering.md b/docs/rules/order/ordering.md index 421c8360..5e0d0092 100644 --- a/docs/rules/order/ordering.md +++ b/docs/rules/order/ordering.md @@ -9,7 +9,7 @@ title: "ordering | Solhint" ![Default Severity Badge warn](https://img.shields.io/badge/Default%20Severity-warn-yellow) ## Description -Check order of elements in file and inside each contract, according to the style guide +Check order of elements in file and inside each contract, according to the style guide. ## Options This rule accepts a string option of rule severity. Must be one of "error", "warn", "off". Default to warn. diff --git a/lib/rules/best-practises/no-console.js b/lib/rules/best-practises/no-console.js index 485c0204..e6b26af6 100644 --- a/lib/rules/best-practises/no-console.js +++ b/lib/rules/best-practises/no-console.js @@ -5,7 +5,7 @@ const meta = { type: 'best-practises', docs: { description: - 'No console.log/logInt/logBytesX/logString/etc & No hardhat and forge-std console.sol import statements', + 'No console.log/logInt/logBytesX/logString/etc & No hardhat and forge-std console.sol import statements.', category: 'Best Practise Rules', examples: { bad: [ diff --git a/lib/rules/best-practises/no-global-import.js b/lib/rules/best-practises/no-global-import.js index 2f3e27b9..a4e337ac 100644 --- a/lib/rules/best-practises/no-global-import.js +++ b/lib/rules/best-practises/no-global-import.js @@ -5,7 +5,7 @@ const meta = { type: 'best-practises', docs: { - description: 'Import statement includes an entire file instead of selected symbols', + description: 'Import statement includes an entire file instead of selected symbols.', category: 'Best Practise Rules', examples: { bad: [ diff --git a/lib/rules/best-practises/no-unused-import.js b/lib/rules/best-practises/no-unused-import.js index 5e801001..78ba6f72 100644 --- a/lib/rules/best-practises/no-unused-import.js +++ b/lib/rules/best-practises/no-unused-import.js @@ -6,7 +6,7 @@ const meta = { type: 'best-practises', docs: { - description: 'Imported name is not used', + description: 'Imported name is not used.', category: 'Best Practise Rules', }, diff --git a/lib/rules/naming/const-name-snakecase.js b/lib/rules/naming/const-name-snakecase.js index dc10fded..9a57335c 100644 --- a/lib/rules/naming/const-name-snakecase.js +++ b/lib/rules/naming/const-name-snakecase.js @@ -6,7 +6,7 @@ const meta = { type: 'naming', docs: { - description: 'Constant name must be in capitalized SNAKE_CASE.', + description: 'Constant name must be in capitalized SNAKE_CASE. (Does not check IMMUTABLES, use immutable-vars-naming)', category: 'Style Guide Rules', }, diff --git a/lib/rules/naming/func-param-name-mixedcase.js b/lib/rules/naming/func-param-name-mixedcase.js index 204c49bf..56dae1f5 100644 --- a/lib/rules/naming/func-param-name-mixedcase.js +++ b/lib/rules/naming/func-param-name-mixedcase.js @@ -6,7 +6,7 @@ const meta = { type: 'naming', docs: { - description: 'Function param name must be in mixedCase', + description: 'Function param name must be in mixedCase.', category: 'Style Guide Rules', }, diff --git a/lib/rules/naming/immutable-vars-naming.js b/lib/rules/naming/immutable-vars-naming.js new file mode 100644 index 00000000..5a26d3b6 --- /dev/null +++ b/lib/rules/naming/immutable-vars-naming.js @@ -0,0 +1,80 @@ +const BaseChecker = require('../base-checker') +const naming = require('../../common/identifier-naming') +const { severityDescription } = require('../../doc/utils') + +const DEFAULT_INMUTABLE_AS_CONSTANTS = true +const DEFAULT_SEVERITY = 'warn' +const DEFAULT_OPTION = { immutablesAsConstants: DEFAULT_INMUTABLE_AS_CONSTANTS } + +const ruleId = 'immutable-vars-naming' +const meta = { + type: 'naming', + + docs: { + description: + 'Check Immutable variables. Capitalized SNAKE_CASE or mixedCase depending on configuration.', + category: 'Style Guide Rules', + options: [ + { + description: severityDescription, + default: DEFAULT_SEVERITY, + }, + { + description: + 'A JSON object with a single property "immutablesAsConstants" as boolean specifying if immutable variables should be treated as constants', + default: JSON.stringify(DEFAULT_OPTION), + }, + ], + }, + + isDefault: false, + recommended: true, + defaultSetup: [DEFAULT_SEVERITY, DEFAULT_OPTION], + + schema: { + type: 'object', + properties: { + immutablesAsConstants: { + type: 'boolean', + }, + }, + }, +} + +class ImmutableVarsNamingChecker extends BaseChecker { + constructor(reporter, config) { + super(reporter, ruleId, meta) + + this.treatImmutablesAsConstants = + config && + config.getObjectPropertyBoolean( + ruleId, + 'immutablesAsConstants', + DEFAULT_INMUTABLE_AS_CONSTANTS + ) + } + + VariableDeclaration(node) { + if (node.isImmutable) { + if (this.treatImmutablesAsConstants) { + this.validateImmutableAsConstantName(node) + } else { + this.validateImmutableAsRegularVariables(node) + } + } + } + + validateImmutableAsConstantName(node) { + if (naming.isNotUpperSnakeCase(node.name)) { + this.error(node, 'Immutable variables name are set to be in capitalized SNAKE_CASE') + } + } + + validateImmutableAsRegularVariables(node) { + if (naming.isNotMixedCase(node.name)) { + this.error(node, 'Immutable variables names are set to be in mixedCase') + } + } +} + +module.exports = ImmutableVarsNamingChecker diff --git a/lib/rules/naming/index.js b/lib/rules/naming/index.js index ad0a9e55..60db92c4 100644 --- a/lib/rules/naming/index.js +++ b/lib/rules/naming/index.js @@ -4,10 +4,11 @@ const EventNameCamelcaseChecker = require('./event-name-camelcase') const FuncNameMixedcaseChecker = require('./func-name-mixedcase') const FuncParamNameMixedcaseChecker = require('./func-param-name-mixedcase') const ModifierNameMixedcaseChecker = require('./modifier-name-mixedcase') -const PrivateVarsLeadingUnderscore = require('./private-vars-leading-underscore') +const PrivateVarsLeadingUnderscoreChecker = require('./private-vars-leading-underscore') const UseForbiddenNameChecker = require('./use-forbidden-name') const VarNameMixedcaseChecker = require('./var-name-mixedcase') -const NamedParametersMapping = require('./named-parameters-mapping') +const NamedParametersMappingChecker = require('./named-parameters-mapping') +const ImmutableVarsNamingChecker = require('./immutable-vars-naming') module.exports = function checkers(reporter, config) { return [ @@ -17,9 +18,10 @@ module.exports = function checkers(reporter, config) { new FuncNameMixedcaseChecker(reporter), new FuncParamNameMixedcaseChecker(reporter), new ModifierNameMixedcaseChecker(reporter), - new PrivateVarsLeadingUnderscore(reporter, config), + new PrivateVarsLeadingUnderscoreChecker(reporter, config), new UseForbiddenNameChecker(reporter), new VarNameMixedcaseChecker(reporter), - new NamedParametersMapping(reporter), + new NamedParametersMappingChecker(reporter), + new ImmutableVarsNamingChecker(reporter, config), ] } diff --git a/lib/rules/naming/named-parameters-mapping.js b/lib/rules/naming/named-parameters-mapping.js index 099e71c2..4452d0da 100644 --- a/lib/rules/naming/named-parameters-mapping.js +++ b/lib/rules/naming/named-parameters-mapping.js @@ -4,7 +4,7 @@ const ruleId = 'named-parameters-mapping' const meta = { type: 'naming', docs: { - description: `Solidity v0.8.18 introduced named parameters on the mappings definition`, + description: `Solidity v0.8.18 introduced named parameters on the mappings definition.`, category: 'Style Guide Rules', examples: { good: [ @@ -60,7 +60,7 @@ const meta = { schema: null, } -class NamedParametersMapping extends BaseChecker { +class NamedParametersMappingChecker extends BaseChecker { constructor(reporter) { super(reporter, ruleId, meta) } @@ -109,4 +109,4 @@ class NamedParametersMapping extends BaseChecker { } } -module.exports = NamedParametersMapping +module.exports = NamedParametersMappingChecker diff --git a/lib/rules/naming/var-name-mixedcase.js b/lib/rules/naming/var-name-mixedcase.js index a7268da4..3e9581c3 100644 --- a/lib/rules/naming/var-name-mixedcase.js +++ b/lib/rules/naming/var-name-mixedcase.js @@ -6,7 +6,7 @@ const meta = { type: 'naming', docs: { - description: `Variable name must be in mixedCase.`, + description: `Variable name must be in mixedCase. (Does not check IMMUTABLES, use immutable-vars-naming)`, category: 'Style Guide Rules', }, @@ -23,7 +23,7 @@ class VarNameMixedcaseChecker extends BaseChecker { } VariableDeclaration(node) { - if (!node.isDeclaredConst) { + if (!node.isDeclaredConst && !node.isImmutable) { this.validateVariablesName(node) } } diff --git a/lib/rules/order/ordering.js b/lib/rules/order/ordering.js index 19c731f6..494f3ad5 100644 --- a/lib/rules/order/ordering.js +++ b/lib/rules/order/ordering.js @@ -6,7 +6,7 @@ const meta = { type: 'order', docs: { - description: `Check order of elements in file and inside each contract, according to the style guide`, + description: `Check order of elements in file and inside each contract, according to the style guide.`, category: 'Style Guide Rules', examples: { good: require('../../../test/fixtures/order/ordering-correct'), diff --git a/test/rules/naming/const-name-snakecase.js b/test/rules/naming/const-name-snakecase.js index 95289ab9..125c5300 100644 --- a/test/rules/naming/const-name-snakecase.js +++ b/test/rules/naming/const-name-snakecase.js @@ -54,4 +54,24 @@ describe('Linter - const-name-snakecase', () => { assert.equal(report.errorCount, 1) assert.ok(report.messages[0].message.includes('SNAKE_CASE')) }) + + it('should not raise const name error for immutable variables in SNAKE_CASE', () => { + const code = contractWith('uint32 private immutable SNAKE_CASE;') + + const report = linter.processStr(code, { + rules: { 'const-name-snakecase': 'error' }, + }) + + assert.equal(report.errorCount, 0) + }) + + it('should not raise const name error for immutable variables in mixedCase', () => { + const code = contractWith('uint32 private immutable SNAKE_CASE;') + + const report = linter.processStr(code, { + rules: { 'const-name-snakecase': 'error' }, + }) + + assert.equal(report.errorCount, 0) + }) }) diff --git a/test/rules/naming/immutable-vars-naming.js b/test/rules/naming/immutable-vars-naming.js new file mode 100644 index 00000000..4b9cb7de --- /dev/null +++ b/test/rules/naming/immutable-vars-naming.js @@ -0,0 +1,117 @@ +const assert = require('assert') +const linter = require('../../../lib/index') +const contractWith = require('../../common/contract-builder').contractWith + +describe('immutable-vars-naming', () => { + it('should not raise error for non immutable variables if rule is off', () => { + const code = contractWith('uint32 private immutable D;') + + const report = linter.processStr(code, { + rules: { + 'immutable-vars-naming': 'off', + 'var-name-mixedcase': 'error', + 'const-name-snakecase': 'error', + }, + }) + + assert.equal(report.errorCount, 0) + }) + + it('should raise error when immutablesAsConstants = false and variable is in snake case', () => { + const code = contractWith('uint32 private immutable SNAKE_CASE;') + + const report = linter.processStr(code, { + rules: { 'immutable-vars-naming': ['error', { immutablesAsConstants: false }] }, + }) + + assert.equal(report.errorCount, 1) + assert.ok( + report.messages[0].message.includes('Immutable variables names are set to be in mixedCase') + ) + }) + + it('should NOT raise error when immutablesAsConstants = false and variable is in snake case', () => { + const code = contractWith('uint32 private immutable SNAKE_CASE;') + + const report = linter.processStr(code, { + rules: { 'immutable-vars-naming': ['error', { immutablesAsConstants: true }] }, + }) + + assert.equal(report.errorCount, 0) + }) + + it('should raise error when immutablesAsConstants = true and variable is in mixedCase', () => { + const code = contractWith('uint32 private immutable mixedCase;') + + const report = linter.processStr(code, { + rules: { 'immutable-vars-naming': ['error', { immutablesAsConstants: true }] }, + }) + + assert.equal(report.errorCount, 1) + assert.ok( + report.messages[0].message.includes( + 'Immutable variables name are set to be in capitalized SNAKE_CASE' + ) + ) + }) + + it('should NOT raise error when immutablesAsConstants = false and variable is in mixedCase', () => { + const code = contractWith('uint32 private immutable mixedCase;') + + const report = linter.processStr(code, { + rules: { 'immutable-vars-naming': ['error', { immutablesAsConstants: false }] }, + }) + + assert.equal(report.errorCount, 0) + }) + + describe('immutable-vars-naming ==> warnings (same as above)', () => { + it('should raise warning when immutablesAsConstants = false and variable is in snake case', () => { + const code = contractWith('uint32 private immutable SNAKE_CASE;') + + const report = linter.processStr(code, { + rules: { 'immutable-vars-naming': ['warn', { immutablesAsConstants: false }] }, + }) + + assert.equal(report.warningCount, 1) + assert.ok( + report.messages[0].message.includes('Immutable variables names are set to be in mixedCase') + ) + }) + + it('should NOT raise warning when immutablesAsConstants = false and variable is in snake case', () => { + const code = contractWith('uint32 private immutable SNAKE_CASE;') + + const report = linter.processStr(code, { + rules: { 'immutable-vars-naming': ['warn', { immutablesAsConstants: true }] }, + }) + + assert.equal(report.warningCount, 0) + }) + + it('should raise warning when immutablesAsConstants = true and variable is in mixedCase', () => { + const code = contractWith('uint32 private immutable mixedCase;') + + const report = linter.processStr(code, { + rules: { 'immutable-vars-naming': ['warn', { immutablesAsConstants: true }] }, + }) + + assert.equal(report.warningCount, 1) + assert.ok( + report.messages[0].message.includes( + 'Immutable variables name are set to be in capitalized SNAKE_CASE' + ) + ) + }) + + it('should NOT raise warning when immutablesAsConstants = false and variable is in mixedCase', () => { + const code = contractWith('uint32 private immutable mixedCase;') + + const report = linter.processStr(code, { + rules: { 'immutable-vars-naming': ['warn', { immutablesAsConstants: false }] }, + }) + + assert.equal(report.warningCount, 0) + }) + }) +}) diff --git a/test/rules/naming/var-name-mixedcase.js b/test/rules/naming/var-name-mixedcase.js index 13fa86eb..635a7924 100644 --- a/test/rules/naming/var-name-mixedcase.js +++ b/test/rules/naming/var-name-mixedcase.js @@ -46,4 +46,24 @@ describe('Linter - var-name-mixedcase', () => { assert.equal(report.errorCount, 0) }) + + it('should not raise const name error for immutable variables in SNAKE_CASE', () => { + const code = contractWith('uint32 private immutable SNAKE_CASE;') + + const report = linter.processStr(code, { + rules: { 'no-unused-vars': 'error', 'var-name-mixedcase': 'error' }, + }) + + assert.equal(report.errorCount, 0) + }) + + it('should not raise const name error for immutable variables in mixedCase', () => { + const code = contractWith('uint32 private immutable SNAKE_CASE;') + + const report = linter.processStr(code, { + rules: { 'no-unused-vars': 'error', 'var-name-mixedcase': 'error' }, + }) + + assert.equal(report.errorCount, 0) + }) })