Factory smart contract to make easier and safer usage of the `CREATE` and `CREATE2` EVM opcodes as well as of `CREATE3`-based (i.e. without an initcode factor) contract creations.
This PR scaffolds the test architecture as follows:
To facilitate testing, all private variables and methods in CreateX are now internal. Since CreateX will be deployed directly and users/developers will never inherit from it, there is no practical difference between these two visibilities, and internal allows us to directly test everything.
test/BaseTest.sol is the base contract that all of our tests will inherit from. It does two things:
Defines a CreateXHarness contract that will expose internal methods for testing. It uses the naming convention of expose_InternalMethodName that we came up with when writing the foundry best practices
Defines BaseTest which is the test contract that we'll be inheriting from. This contract deploys the CreateX and CreateXHarness contracts, and defines events and helper methods that will commonly be needed.
Now for the actual tests. We start by focusing on unit tests to ensure everything is well spec'd out. To do this, we'll ultimately remove the existing CreateX.t.sol file but I left it for now. To define the requirements for each method in CreateX we:
Create a spec file called CreateX.{methodName}.tree. You can see an example of this for the _efficientHash function, which was a simple initial example.
These spec files will be very similar to Paul's Branching Tree Technique approach for specs, which is like a lightweight version of gherkin/cucumber (1, 2).
The rules I am following are similar to Gherkin, in that the flow of the tree should be Given > When > It should (Then). Additionally:
If a method is branchless, it will only have it levels like the current example file
If a method has any conditions (including e.g. checks on inputs), then there should be a Given or When for each.
I'm using bulloak to generate test scaffolding from the spec file. This tool is still a work in progressāand you can see various open/closed issues, PRs, and discussionsābut it does a good job helping with the scaffolding
The resulting structure is that we have CreateX.{methodName}.tree to define a spec for a method, and CreateX.{methodName}.t.sol for the corresponding tests.
This PR scaffolds the test architecture as follows:
private
variables and methods in CreateX are nowinternal
. SinceCreateX
will be deployed directly and users/developers will never inherit from it, there is no practical difference between these two visibilities, andinternal
allows us to directly test everything.test/BaseTest.sol
is the base contract that all of our tests will inherit from. It does two things:CreateXHarness
contract that will expose internal methods for testing. It uses the naming convention ofexpose_InternalMethodName
that we came up with when writing the foundry best practicesBaseTest
which is the test contract that we'll be inheriting from. This contract deploys the CreateX and CreateXHarness contracts, and defines events and helper methods that will commonly be needed.Now for the actual tests. We start by focusing on unit tests to ensure everything is well spec'd out. To do this, we'll ultimately remove the existing
CreateX.t.sol
file but I left it for now. To define the requirements for each method in CreateX we:CreateX.{methodName}.tree
. You can see an example of this for the_efficientHash
function, which was a simple initial example.it
levels like the current example fileCreateX.{methodName}.tree
to define a spec for a method, andCreateX.{methodName}.t.sol
for the corresponding tests.š¶ Cute Animal Picture