diff --git a/docs/rules/naming/foundry-test-functions.md b/docs/rules/naming/foundry-test-functions.md index 534ad6e5..0f20475a 100644 --- a/docs/rules/naming/foundry-test-functions.md +++ b/docs/rules/naming/foundry-test-functions.md @@ -33,7 +33,7 @@ This rule accepts an array of options: - Supported Regex: ```test(Fork)?(Fuzz)?(Fail)?_(Revert(If_|When_){1})?\w{1,}``` - This rule should be executed in a separate folder with a separate .solhint.json => ```solhint --config .solhint.json testFolder/**/*.sol``` - This rule applies only to `external` and `public` functions -- This rule skips the `setUp()` function +- This rule skips the `setUp()` function by default ## Examples ### 👍 Examples of **correct** code for this rule diff --git a/lib/common/identifier-naming.js b/lib/common/identifier-naming.js index efc7e3f5..970bcc71 100644 --- a/lib/common/identifier-naming.js +++ b/lib/common/identifier-naming.js @@ -31,8 +31,18 @@ module.exports = { return text && text[0] === '_' }, - isNotFoundryTestCase(text) { - const regex = /^test(Fork)?(Fuzz)?(Fail)?_(Revert(If_|When_){1})?\w{1,}$/ - return !match(text, regex) + isFoundryTestCase(text) { + // this one checks CamelCase after test keyword + // const regexTest = /^test(Fork)?(Fuzz)?(Fail)?(_)?[A-Z](Revert(If_|When_){1})?\w{1,}$/ + + const regexTest = /^test(Fork)?(Fuzz)?(Fail)?(_)?(Revert(If_|When_){1})?\w{1,}$/ + const matchRegexTest = match(text, regexTest) + + // this one checks CamelCase after test keyword + // const regexInvariant = /^(invariant|statefulFuzz)(_)?[A-Z]\w{1,}$/ + const regexInvariant = /^(invariant|statefulFuzz)(_)?\w{1,}$/ + const matchRegexInvariant = match(text, regexInvariant) + + return matchRegexTest || matchRegexInvariant }, } diff --git a/lib/rules/naming/foundry-test-functions.js b/lib/rules/naming/foundry-test-functions.js index 1cc367a6..4a7b3646 100644 --- a/lib/rules/naming/foundry-test-functions.js +++ b/lib/rules/naming/foundry-test-functions.js @@ -52,7 +52,7 @@ const meta = { note: 'This rule applies only to `external` and `public` functions', }, { - note: 'This rule skips the `setUp()` function', + note: 'This rule skips the `setUp()` function by default', }, ], }, @@ -79,7 +79,7 @@ class FoundryTestFunctionsChecker extends BaseChecker { !this.searchInArray(this.skippedFunctions, node.name) && (node.visibility === 'public' || node.visibility === 'external') ) { - if (naming.isNotFoundryTestCase(node.name)) { + if (!naming.isFoundryTestCase(node.name)) { this.error(node, `Function ${node.name}() must match Foundry test naming convention`) } } diff --git a/test/rules/naming/foundry-test-functions.js b/test/rules/naming/foundry-test-functions.js index 9a0feeb9..53c70cae 100644 --- a/test/rules/naming/foundry-test-functions.js +++ b/test/rules/naming/foundry-test-functions.js @@ -4,6 +4,7 @@ const contractWith = require('../../common/contract-builder').contractWith const { assertErrorCount, assertNoErrors, assertErrorMessage } = require('../../common/asserts') const ALLOWED_FUNCTION_NAMES = [ + 'test', 'test_', 'testFork_', 'testFuzz_', @@ -20,9 +21,14 @@ const ALLOWED_FUNCTION_NAMES = [ 'testFuzz_Revert_', 'testFuzz_If_', 'testFuzz_When_', + 'invariant', + 'invariant_', + 'invariantA', + 'statefulFuzz', + 'statefulFuzz_', ] -const DISALLOWED_FUNCTION_NAMES = ['Test_', 'Test', 'test', 'testo_', '', 'any', 'setUp', 'other'] +const DISALLOWED_FUNCTION_NAMES = ['Test_', 'Test', '', 'any', 'setUp', 'other', '_'] const composeFunctionName = (prefix, name, visibility) => 'function ' + prefix + name + ' ' + visibility + ' { testNumber = 42; }' @@ -33,6 +39,7 @@ describe('Linter - foundry-test-functions', () => { const functionDefinition = composeFunctionName(prefix, 'FunctionName()', 'public') const code = contractWith(functionDefinition) + console.log('`code` :>> ', code) const report = linter.processStr(code, { rules: { 'foundry-test-functions': ['error', ['setUp', 'finish']] }, }) @@ -171,7 +178,7 @@ describe('Linter - foundry-test-functions', () => { ) }) - it(`should NOT raise error only for setUp when rule is just on 'error'`, () => { + it(`should NOT raise error only for setUp when rule is just on 'error' (setUp is default)`, () => { const code = contractWith(` function setUp() public { testNumber = 42; } function finish() public { testNumber = 43; }