diff --git a/test/TestConstants.sol b/test/TestConstants.sol index 76b8f58..304b825 100644 --- a/test/TestConstants.sol +++ b/test/TestConstants.sol @@ -31,3 +31,4 @@ to have a predetermined length. This is that length.*/ uint32 constant _MAX_NR_OF_TEST_LOG_VALUES_PER_LOG_FILE = 26; string constant _TEST_CASE_HIT_RATE_COUNTS_FILENAME = "test_case_hit_rate_counts"; +string constant _TIMESTAMP_FILE_EXT = ".timestamp"; diff --git a/test/WritingToFile.sol b/test/WritingToFile.sol index a19df9d..edd2244 100644 --- a/test/WritingToFile.sol +++ b/test/WritingToFile.sol @@ -43,7 +43,7 @@ contract WritingToFile is PRBTest, StdCheats, IWritingToFile { // Specify the logging directory and filepath. uint256 timeStamp = _createFileIfNotExists( serialisedTextString, - string(abi.encodePacked(testLogTimestampFilePath, ".timestamp")) + string(abi.encodePacked(testLogTimestampFilePath, _TIMESTAMP_FILE_EXT)) ); string memory logDir = string(abi.encodePacked(testLogTimestampFilePath, "/", Strings.toString(timeStamp))); hitRateFilePath = string( diff --git a/test/fuzz/FuzzTestWithHitRateAssertion.sol b/test/fuzz/FuzzTestWithHitRateAssertion.sol index c046ff5..ad7d3ea 100644 --- a/test/fuzz/FuzzTestWithHitRateAssertion.sol +++ b/test/fuzz/FuzzTestWithHitRateAssertion.sol @@ -5,54 +5,49 @@ import { PRBTest } from "@prb/test/src/PRBTest.sol"; import { StdCheats } from "forge-std/src/StdCheats.sol"; import { Vm } from "forge-std/src/Vm.sol"; import "test/TestConstants.sol"; +import { FuzzTestCaseCounter } from "./fuzz_helper/FuzzTestCaseCounter.sol"; import { IterableStringMapping } from "./fuzz_helper/IterableStringMapping.sol"; -import { TestIterableMapping } from "./fuzz_helper/TestIterableMapping.sol"; contract FuzzTestWithHitRateAssertion is PRBTest, StdCheats { using IterableStringMapping for IterableStringMapping.Map; IterableStringMapping.Map private _variableNameMapping; - TestIterableMapping private _logMapping; + FuzzTestCaseCounter private _logMapping; string private _hitRateFilePath; /** The setUp() method is called once each fuzz run.*/ function setUp() public virtual { + // Specify the path to this file, the test file name, and the fuzz test name, used for test case coverage logging. string memory relBareFolderPath = "test_logging/fuzz"; string memory fileNameWithoutExt = "FuzzTestWithHitRateAssertion"; string memory testFunctionName = "testFuzzWithHitRateAssertion"; string memory relTestLogTimestampFilePath = string(abi.encodePacked(relBareFolderPath, "/", fileNameWithoutExt)); - emit Log("relTestLogTimestampFilePath="); - emit Log(relTestLogTimestampFilePath); - vm.createDir(relTestLogTimestampFilePath, true); - vm.createDir(relBareFolderPath, true); - // Delete the temp file at the start of running this test file. - // if (vm.isFile(_LOG_TIME_CREATOR)) { - if (vm.isFile(relTestLogTimestampFilePath)) { - vm.removeFile(relTestLogTimestampFilePath); - /** The _LOG_TIME_CREATOR file is recreated if it does not exist in: `new - TestIterableMapping()` and then the timestamp of that file is taken as - the log dir for that fuzz run. - - If the setUp() function would be called before each fuzz run, then it - would (likely) create 1000 different timestamps if 1000 fuzz runs were - ran. + // Create those directories that will contain the test coverage timestamp and logging files. + vm.createDir(relBareFolderPath, true); + vm.createDir(relTestLogTimestampFilePath, true); - If the setUp() function would be called once before each fuzz run, then - the _LOG_TIME_CREATOR file would be created by the first Fuzz run of a - fuzz test.*/ + /** I do not know exactly why, but per file, this yields a single timestamp regardless of how many fuzz runs are + ran per test function. (As long as 1 fuzz test per file is used).*/ + if (vm.isFile(string(abi.encodePacked(relTestLogTimestampFilePath, _TIMESTAMP_FILE_EXT)))) { + vm.removeFile(string(abi.encodePacked(relTestLogTimestampFilePath, _TIMESTAMP_FILE_EXT))); } - _logMapping = new TestIterableMapping(relTestLogTimestampFilePath, testFunctionName); + // Set up test case hit counter logging. + _logMapping = new FuzzTestCaseCounter(relTestLogTimestampFilePath, testFunctionName); + // Specify which test cases are logged within this test file. _variableNameMapping.set("LargerThan", "a"); _variableNameMapping.set("SmallerThan", "b"); _variableNameMapping.set("Total", "c"); } - /** - @dev The investor has invested 0.5 eth, and the investment target is 0.6 eth after 12 weeks. - So the investment target is not reached, so all the funds should be returned. + /** Example of a basic fuzz test with a random variable. After the test, you can go to: + + // + _counter.txt + + to see how often each test case was hit. */ function testFuzzDebugtestFuzzWithHitRateAssertion(uint256 randomValue) public virtual { _logMapping.readHitRatesFromLogFileAndSetToMap(_logMapping.getHitRateFilePath()); @@ -66,8 +61,10 @@ contract FuzzTestWithHitRateAssertion is PRBTest, StdCheats { _logMapping.overwriteExistingMapLogFile(_logMapping.getHitRateFilePath()); } + /**Increments the test case hit counts in the testIterableMapping + */ function _incrementLogCount( - TestIterableMapping logMapping, + FuzzTestCaseCounter logMapping, IterableStringMapping.Map storage variableNameMapping, string memory variableName ) internal virtual { diff --git a/test/fuzz/FuzzTestWithHitRateAssertionCopy.sol b/test/fuzz/FuzzTestWithHitRateAssertionCopy.sol index 48948fa..2623529 100644 --- a/test/fuzz/FuzzTestWithHitRateAssertionCopy.sol +++ b/test/fuzz/FuzzTestWithHitRateAssertionCopy.sol @@ -5,14 +5,14 @@ import { PRBTest } from "@prb/test/src/PRBTest.sol"; import { StdCheats } from "forge-std/src/StdCheats.sol"; import { Vm } from "forge-std/src/Vm.sol"; import "test/TestConstants.sol"; +import { FuzzTestCaseCounter } from "./fuzz_helper/FuzzTestCaseCounter.sol"; import { IterableStringMapping } from "./fuzz_helper/IterableStringMapping.sol"; -import { TestIterableMapping } from "./fuzz_helper/TestIterableMapping.sol"; contract FuzzTestWithHitRateAssertionCopy is PRBTest, StdCheats { using IterableStringMapping for IterableStringMapping.Map; IterableStringMapping.Map private _variableNameMapping; - TestIterableMapping private _logMapping; + FuzzTestCaseCounter private _logMapping; string private _hitRateFilePath; @@ -32,7 +32,7 @@ contract FuzzTestWithHitRateAssertionCopy is PRBTest, StdCheats { if (vm.isFile(relTestLogTimestampFilePath)) { vm.removeFile(relTestLogTimestampFilePath); /** The _LOG_TIME_CREATOR file is recreated if it does not exist in: `new - TestIterableMapping()` and then the timestamp of that file is taken as + FuzzTestCaseCounter()` and then the timestamp of that file is taken as the log dir for that fuzz run. If the setUp() function would be called before each fuzz run, then it @@ -43,7 +43,7 @@ contract FuzzTestWithHitRateAssertionCopy is PRBTest, StdCheats { the _LOG_TIME_CREATOR file would be created by the first Fuzz run of a fuzz test.*/ } - _logMapping = new TestIterableMapping(relTestLogTimestampFilePath, testFunctionName); + _logMapping = new FuzzTestCaseCounter(relTestLogTimestampFilePath, testFunctionName); _variableNameMapping.set("LargerThan", "a"); _variableNameMapping.set("SmallerThan", "b"); @@ -67,7 +67,7 @@ contract FuzzTestWithHitRateAssertionCopy is PRBTest, StdCheats { } function _incrementLogCount( - TestIterableMapping logMapping, + FuzzTestCaseCounter logMapping, IterableStringMapping.Map storage variableNameMapping, string memory variableName ) internal virtual { diff --git a/test/fuzz/fuzz_helper/TestIterableMapping.sol b/test/fuzz/fuzz_helper/FuzzTestCaseCounter.sol similarity index 99% rename from test/fuzz/fuzz_helper/TestIterableMapping.sol rename to test/fuzz/fuzz_helper/FuzzTestCaseCounter.sol index 8b812e2..b50e151 100644 --- a/test/fuzz/fuzz_helper/TestIterableMapping.sol +++ b/test/fuzz/fuzz_helper/FuzzTestCaseCounter.sol @@ -59,7 +59,7 @@ struct LogParams { uint256 z; } -contract TestIterableMapping is PRBTest, StdCheats { +contract FuzzTestCaseCounter is PRBTest, StdCheats { using IterableUint256Mapping for IterableUint256Mapping.Map; IterableUint256Mapping.Map private _uint256Map;