From 3a10a5ec427549947b43324ed75e40ce1dfe096c Mon Sep 17 00:00:00 2001 From: ernestognw Date: Fri, 14 Jul 2023 15:05:49 -0600 Subject: [PATCH 1/2] Allow use of variables starting with `$` in `var-name-mixedcase` --- lib/common/identifier-naming.js | 2 +- test/rules/naming/var-name-mixedcase.js | 17 +++++++++++++++++ 2 files changed, 18 insertions(+), 1 deletion(-) diff --git a/lib/common/identifier-naming.js b/lib/common/identifier-naming.js index 2a969a89..a7f5ea74 100644 --- a/lib/common/identifier-naming.js +++ b/lib/common/identifier-naming.js @@ -4,7 +4,7 @@ function match(text, regex) { module.exports = { isMixedCase(text) { - return match(text, /[_]*[a-z]+[a-zA-Z0-9$]*[_]?/) + return match(text, /[_]*[a-z$]+[a-zA-Z0-9$]*[_]?/) }, isNotMixedCase(text) { diff --git a/test/rules/naming/var-name-mixedcase.js b/test/rules/naming/var-name-mixedcase.js index 13fa86eb..c02fe10a 100644 --- a/test/rules/naming/var-name-mixedcase.js +++ b/test/rules/naming/var-name-mixedcase.js @@ -46,4 +46,21 @@ describe('Linter - var-name-mixedcase', () => { assert.equal(report.errorCount, 0) }) + + const WITH_$ = { + $: contractWith('uint32 private $ = 10;'), + 'starting with $': contractWith('uint32 private $D = 10;'), + 'containing a $': contractWith('uint32 private testWith$Contained = 10;'), + 'ending with $': contractWith('uint32 private testWithEnding$ = 10;'), + } + + for (const [key, code] of Object.entries(WITH_$)) { + it(`should not raise var name error for variables ${key}`, () => { + const report = linter.processStr(code, { + rules: { 'no-unused-vars': 'error', 'var-name-mixedcase': 'error' }, + }) + + assert.equal(report.errorCount, 0) + }) + } }) From 3922c78c00c1697c72e9419b35317cd3243b04ee Mon Sep 17 00:00:00 2001 From: ernestognw Date: Wed, 19 Jul 2023 14:38:56 -0600 Subject: [PATCH 2/2] Complete $ support for every identifier naming --- lib/common/identifier-naming.js | 4 +- lib/rules/naming/contract-name-camelcase.js | 2 +- lib/rules/naming/func-param-name-mixedcase.js | 2 +- test/rules/naming/const-name-snakecase.js | 19 +++ test/rules/naming/contract-name-camelcase.js | 129 +++++++++++++++--- test/rules/naming/event-name-camelcase.js | 29 ++++ test/rules/naming/func-name-mixedcase.js | 21 ++- .../rules/naming/func-param-name-mixedcase.js | 86 ++++++++++-- test/rules/naming/modifier-name-mixedcase.js | 19 +++ test/rules/naming/var-name-mixedcase.js | 30 ++-- 10 files changed, 292 insertions(+), 49 deletions(-) diff --git a/lib/common/identifier-naming.js b/lib/common/identifier-naming.js index a7f5ea74..1444d398 100644 --- a/lib/common/identifier-naming.js +++ b/lib/common/identifier-naming.js @@ -12,7 +12,7 @@ module.exports = { }, isCamelCase(text) { - return match(text, /[A-Z]+[a-zA-Z0-9$]*/) + return match(text, /[A-Z$]+[a-zA-Z0-9$]*/) }, isNotCamelCase(text) { @@ -20,7 +20,7 @@ module.exports = { }, isUpperSnakeCase(text) { - return match(text, /_{0,2}[A-Z0-9]+[_A-Z0-9]*/) + return match(text, /_{0,2}[A-Z0-9$]+[_A-Z0-9$]*/) }, isNotUpperSnakeCase(text) { diff --git a/lib/rules/naming/contract-name-camelcase.js b/lib/rules/naming/contract-name-camelcase.js index 2d39a88a..336e7806 100644 --- a/lib/rules/naming/contract-name-camelcase.js +++ b/lib/rules/naming/contract-name-camelcase.js @@ -6,7 +6,7 @@ const meta = { type: 'naming', docs: { - description: 'Contract name must be in CamelCase.', + description: 'Contract, struct and enum names must be in CamelCase.', 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..bf81bc26 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 and event param names must be in mixedCase', category: 'Style Guide Rules', }, diff --git a/test/rules/naming/const-name-snakecase.js b/test/rules/naming/const-name-snakecase.js index 95289ab9..71dea9f4 100644 --- a/test/rules/naming/const-name-snakecase.js +++ b/test/rules/naming/const-name-snakecase.js @@ -54,4 +54,23 @@ describe('Linter - const-name-snakecase', () => { assert.equal(report.errorCount, 1) assert.ok(report.messages[0].message.includes('SNAKE_CASE')) }) + + describe('with $ character', () => { + const WITH_$ = { + $: contractWith('uint32 private constant $ = 10;'), + 'starting with $': contractWith('uint32 private constant $THE_CONSTANT = 10;'), + 'containing a $': contractWith('uint32 private constant THE_$_CONSTANT = 10;'), + 'ending with $': contractWith('uint32 private constant THE_CONSTANT$ = 10;'), + } + + for (const [key, code] of Object.entries(WITH_$)) { + it(`should not raise event name error for events ${key}`, () => { + const report = linter.processStr(code, { + rules: { 'const-name-snakecase': 'error' }, + }) + + assert.equal(report.errorCount, 0) + }) + } + }) }) diff --git a/test/rules/naming/contract-name-camelcase.js b/test/rules/naming/contract-name-camelcase.js index 02f98696..5af975dd 100644 --- a/test/rules/naming/contract-name-camelcase.js +++ b/test/rules/naming/contract-name-camelcase.js @@ -3,36 +3,129 @@ const linter = require('../../../lib/index') const contractWith = require('../../common/contract-builder').contractWith describe('Linter - contract-name-camelcase', () => { - it('should raise struct name error', () => { - const code = contractWith('struct a {}') + describe('in structs', () => { + it('should raise contract name error', () => { + const code = contractWith('struct a {}') - const report = linter.processStr(code, { - rules: { 'contract-name-camelcase': 'error' }, + const report = linter.processStr(code, { + rules: { 'contract-name-camelcase': 'error' }, + }) + + assert.equal(report.errorCount, 1) + assert.ok(report.messages[0].message.includes('CamelCase')) + }) + + it('should not raise contract name error', () => { + const code = contractWith('struct MyStruct {}') + + const report = linter.processStr(code, { + rules: { 'contract-name-camelcase': 'error' }, + }) + + assert.equal(report.errorCount, 0) }) - assert.equal(report.errorCount, 1) - assert.ok(report.messages[0].message.includes('CamelCase')) + describe('with $ character', () => { + const WITH_$ = { + $: contractWith('struct $ {}'), + 'starting with $': contractWith('struct $MyStruct {}'), + 'containing a $': contractWith('struct My$Struct {}'), + 'ending with $': contractWith('struct MyStruct$ {}'), + } + + for (const [key, code] of Object.entries(WITH_$)) { + it(`should not raise contract name error for structs ${key}`, () => { + const report = linter.processStr(code, { + rules: { 'contract-name-camelcase': 'error' }, + }) + + assert.equal(report.errorCount, 0) + }) + } + }) }) - it('should raise contract name error', () => { - const code = 'contract a {}' + describe('in contracts', () => { + it('should raise contract name error', () => { + const code = 'contract a {}' + + const report = linter.processStr(code, { + rules: { 'contract-name-camelcase': 'error' }, + }) + + assert.equal(report.errorCount, 1) + assert.ok(report.messages[0].message.includes('CamelCase')) + }) + + it('should not raise contract name error', () => { + const code = 'contract MyContract {}' - const report = linter.processStr(code, { - rules: { 'contract-name-camelcase': 'error' }, + const report = linter.processStr(code, { + rules: { 'contract-name-camelcase': 'error' }, + }) + + assert.equal(report.errorCount, 0) }) - assert.equal(report.errorCount, 1) - assert.ok(report.messages[0].message.includes('CamelCase')) + describe('with $ character', () => { + const WITH_$ = { + $: 'contract $ {}', + 'starting with $': 'contract $MyContract {}', + 'containing a $': 'contract My$Contract {}', + 'ending with $': 'contract MyContract$ {}', + } + + for (const [key, code] of Object.entries(WITH_$)) { + it(`should not raise contract name error for contracts ${key}`, () => { + const report = linter.processStr(code, { + rules: { 'contract-name-camelcase': 'error' }, + }) + + assert.equal(report.errorCount, 0) + }) + } + }) }) - it('should raise enum name error', () => { - const code = contractWith('enum abc {}') + describe('in enums', () => { + it('should raise contract name error', () => { + const code = contractWith('enum abc {}') + + const report = linter.processStr(code, { + rules: { 'contract-name-camelcase': 'error' }, + }) + + assert.equal(report.errorCount, 1) + assert.ok(report.messages[0].message.includes('CamelCase')) + }) + + it('should not raise contract name error', () => { + const code = contractWith('enum MyEnum {}') + + const report = linter.processStr(code, { + rules: { 'contract-name-camelcase': 'error' }, + }) - const report = linter.processStr(code, { - rules: { 'contract-name-camelcase': 'error' }, + assert.equal(report.errorCount, 0) }) - assert.equal(report.errorCount, 1) - assert.ok(report.messages[0].message.includes('CamelCase')) + describe('with $ character', () => { + const WITH_$ = { + $: contractWith('enum $ {}'), + 'starting with $': contractWith('enum $MyEnum {}'), + 'containing a $': contractWith('enum My$Enum {}'), + 'ending with $': contractWith('enum MyEnum$ {}'), + } + + for (const [key, code] of Object.entries(WITH_$)) { + it(`should not raise contract name error for structs ${key}`, () => { + const report = linter.processStr(code, { + rules: { 'contract-name-camelcase': 'error' }, + }) + + assert.equal(report.errorCount, 0) + }) + } + }) }) }) diff --git a/test/rules/naming/event-name-camelcase.js b/test/rules/naming/event-name-camelcase.js index 9c0dd2db..b6927690 100644 --- a/test/rules/naming/event-name-camelcase.js +++ b/test/rules/naming/event-name-camelcase.js @@ -13,4 +13,33 @@ describe('Linter - event-name-camelcase', () => { assert.equal(report.errorCount, 1) assert.ok(report.messages[0].message.includes('CamelCase')) }) + + it('should not raise event name error for event in camelCase', () => { + const code = contractWith('event Event1(uint a);') + + const report = linter.processStr(code, { + rules: { 'event-name-camelcase': 'error' }, + }) + + assert.equal(report.errorCount, 0) + }) + + describe('with $ character', () => { + const WITH_$ = { + $: contractWith('event $(uint a);'), + 'starting with $': contractWith('event $Event1(uint a);'), + 'containing a $': contractWith('event Eve$nt1(uint a);'), + 'ending with $': contractWith('event Event1$(uint a);'), + } + + for (const [key, code] of Object.entries(WITH_$)) { + it(`should not raise event name error for events ${key}`, () => { + const report = linter.processStr(code, { + rules: { 'contract-name-camelcase': 'error' }, + }) + + assert.equal(report.errorCount, 0) + }) + } + }) }) diff --git a/test/rules/naming/func-name-mixedcase.js b/test/rules/naming/func-name-mixedcase.js index fe9d62c8..4cc03390 100644 --- a/test/rules/naming/func-name-mixedcase.js +++ b/test/rules/naming/func-name-mixedcase.js @@ -14,7 +14,7 @@ describe('Linter - func-name-mixedcase', () => { assert.ok(report.messages[0].message.includes('mixedCase')) }) - it('should dot raise incorrect func name error', () => { + it('should not raise incorrect func name error', () => { const code = contractWith('function aFunc1Nam23e () public {}') const report = linter.processStr(code, { @@ -23,4 +23,23 @@ describe('Linter - func-name-mixedcase', () => { assert.equal(report.errorCount, 0) }) + + describe('with $ character', () => { + const WITH_$ = { + $: contractWith('function $ () public {}'), + 'starting with $': contractWith('function $aFunc1Nam23e () public {}'), + 'containing a $': contractWith('function aFunc$1Nam23e () public {}'), + 'ending with $': contractWith('function aFunc1Nam23e$ () public {}'), + } + + for (const [key, code] of Object.entries(WITH_$)) { + it(`should not raise func name error for functions ${key}`, () => { + const report = linter.processStr(code, { + rules: { 'func-name-mixedcase': 'error' }, + }) + + assert.equal(report.errorCount, 0) + }) + } + }) }) diff --git a/test/rules/naming/func-param-name-mixedcase.js b/test/rules/naming/func-param-name-mixedcase.js index 5d7169da..2db17145 100644 --- a/test/rules/naming/func-param-name-mixedcase.js +++ b/test/rules/naming/func-param-name-mixedcase.js @@ -3,25 +3,87 @@ const linter = require('../../../lib/index') const contractWith = require('../../common/contract-builder').contractWith describe('Linter - func-param-name-mixedcase', () => { - it('should raise incorrect func param name error', () => { - const code = contractWith('function funcName (uint A) public {}') + describe('in functions', () => { + it('should raise incorrect func param name error', () => { + const code = contractWith('function funcName (uint A) public {}') - const report = linter.processStr(code, { - rules: { 'func-param-name-mixedcase': 'error' }, + const report = linter.processStr(code, { + rules: { 'func-param-name-mixedcase': 'error' }, + }) + + assert.equal(report.errorCount, 1) + assert.ok(report.messages[0].message.includes('param')) + }) + + it('should not raise incorrect func param name error', () => { + const code = contractWith('function funcName (uint someParam) public {}') + + const report = linter.processStr(code, { + rules: { 'func-param-name-mixedcase': 'error' }, + }) + + assert.equal(report.errorCount, 0) }) - assert.equal(report.errorCount, 1) - assert.ok(report.messages[0].message.includes('param')) + describe('with $ character', () => { + const WITH_$ = { + $: contractWith('function funcName (uint $) public {}'), + 'starting with $': contractWith('function funcName (uint $param) public {}'), + 'containing a $': contractWith('function funcName (uint pa$ram) public {}'), + 'ending with $': contractWith('function funcName (uint param$) public {}'), + } + + for (const [key, code] of Object.entries(WITH_$)) { + it(`should not raise func param name error for parameters ${key}`, () => { + const report = linter.processStr(code, { + rules: { 'func-param-name-mixedcase': 'error' }, + }) + + assert.equal(report.errorCount, 0) + }) + } + }) }) - it('should raise var name error for event arguments illegal styling', () => { - const code = contractWith('event Event1(uint B);') + describe('in events', () => { + it('should raise var name error for event arguments illegal styling', () => { + const code = contractWith('event Event1(uint B);') - const report = linter.processStr(code, { - rules: { 'func-param-name-mixedcase': 'error' }, + const report = linter.processStr(code, { + rules: { 'func-param-name-mixedcase': 'error' }, + }) + + assert.equal(report.errorCount, 1) + assert.ok(report.messages[0].message.includes('mixedCase')) + }) + + it('should not raise incorrect func param name error', () => { + const code = contractWith('event Event1(uint someParam);') + + const report = linter.processStr(code, { + rules: { 'func-param-name-mixedcase': 'error' }, + }) + + assert.equal(report.errorCount, 0) }) - assert.equal(report.errorCount, 1) - assert.ok(report.messages[0].message.includes('mixedCase')) + describe('with $ character', () => { + const WITH_$ = { + $: contractWith('event Event1(uint $);'), + 'starting with $': contractWith('event Event1(uint $param);'), + 'containing a $': contractWith('event Event1(uint pa$ram);'), + 'ending with $': contractWith('event Event1(uint param$);'), + } + + for (const [key, code] of Object.entries(WITH_$)) { + it(`should not raise func name error for functions ${key}`, () => { + const report = linter.processStr(code, { + rules: { 'func-name-mixedcase': 'error' }, + }) + + assert.equal(report.errorCount, 0) + }) + } + }) }) }) diff --git a/test/rules/naming/modifier-name-mixedcase.js b/test/rules/naming/modifier-name-mixedcase.js index a652c156..c35422b5 100644 --- a/test/rules/naming/modifier-name-mixedcase.js +++ b/test/rules/naming/modifier-name-mixedcase.js @@ -23,4 +23,23 @@ describe('Linter - modifier-name-mixedcase', () => { assert.equal(report.errorCount, 0) }) + + describe('with $ character', () => { + const WITH_$ = { + $: contractWith('modifier $(address a) { }'), + 'starting with $': contractWith('modifier $ownedBy(address a) { }'), + 'containing a $': contractWith('modifier owned$By(address a) { }'), + 'ending with $': contractWith('modifier ownedBy$(address a) { }'), + } + + for (const [key, code] of Object.entries(WITH_$)) { + it(`should not raise func name error for functions ${key}`, () => { + const report = linter.processStr(code, { + rules: { 'modifier-name-mixedcase': 'error' }, + }) + + assert.equal(report.errorCount, 0) + }) + } + }) }) diff --git a/test/rules/naming/var-name-mixedcase.js b/test/rules/naming/var-name-mixedcase.js index c02fe10a..e73c768a 100644 --- a/test/rules/naming/var-name-mixedcase.js +++ b/test/rules/naming/var-name-mixedcase.js @@ -47,20 +47,22 @@ describe('Linter - var-name-mixedcase', () => { assert.equal(report.errorCount, 0) }) - const WITH_$ = { - $: contractWith('uint32 private $ = 10;'), - 'starting with $': contractWith('uint32 private $D = 10;'), - 'containing a $': contractWith('uint32 private testWith$Contained = 10;'), - 'ending with $': contractWith('uint32 private testWithEnding$ = 10;'), - } + describe('with $ character', () => { + const WITH_$ = { + $: contractWith('uint32 private $ = 10;'), + 'starting with $': contractWith('uint32 private $D = 10;'), + 'containing a $': contractWith('uint32 private testWith$Contained = 10;'), + 'ending with $': contractWith('uint32 private testWithEnding$ = 10;'), + } - for (const [key, code] of Object.entries(WITH_$)) { - it(`should not raise var name error for variables ${key}`, () => { - const report = linter.processStr(code, { - rules: { 'no-unused-vars': 'error', 'var-name-mixedcase': 'error' }, - }) + for (const [key, code] of Object.entries(WITH_$)) { + it(`should not raise var name error for variables ${key}`, () => { + const report = linter.processStr(code, { + rules: { 'no-unused-vars': 'error', 'var-name-mixedcase': 'error' }, + }) - assert.equal(report.errorCount, 0) - }) - } + assert.equal(report.errorCount, 0) + }) + } + }) })