-
Notifications
You must be signed in to change notification settings - Fork 678
Issue 678: Testing solidity strings with getters/setters #218
Conversation
…h a shorter string with setters
…h a shorter string with setters
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looks good to me!
Looks like a lot of commits for relatively small net change - I'd recommend squashing the commits and doing |
test/DynamicStringLength.sol
Outdated
|
||
contract DynamicStringLength { | ||
string public testString; | ||
uint public testId = 246; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
looks like this & the event aren't used
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Good catch.
test/solidity_dynamic_strings.js
Outdated
const path = require("path"); | ||
const compileAndDeploy = require("./helpers/contracts").compileAndDeploy; | ||
|
||
const mnemonic = "candy maple cake sugar pudding cream honey rich smooth crumble sweet treat"; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The mnemonic defines the list of accounts that ganache will use - but you're using web3.eth.getAccounts below (which is good) so there's no need to hard code a mnemonic.
It's better if tests use randomized accounts - we want tests to look like best practice code examples.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Great suggestions for overall refactoring efforts.
test/solidity_dynamic_strings.js
Outdated
} | ||
|
||
describe("Solidity variable string length", function() { | ||
const context = setUp(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
readability: since this is the only place the setUp
function is called, I'm not sure what value it's providing. The usual flow for mocha tests is as shown in the snippet below, and this breaks that flow
describe(...
describe( ...
before(...
it(...
after(...
}
}
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Great suggestions for overall refactoring efforts.
test/solidity_dynamic_strings.js
Outdated
|
||
before("setup web3", async function() { | ||
context.provider = Ganache.provider(context.options); | ||
context.options.blockTime = 2000; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I wouldn't set a block time - will just make the test slow
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
FWIW, only ever set block time if you're explicitly testing interval mining
test/solidity_dynamic_strings.js
Outdated
before("compile source", async function() { | ||
this.timeout(10000); | ||
context.contractArtifact = await compileAndDeploy( | ||
path.join(__dirname, ".", `${contractName}.sol`), |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
no need to do __dirname, ".", contractFileName
-- the dot is implicit - it's like saying /./contractName.sol
which is the same as /contractName.sol
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Great suggestions for overall refactoring efforts.
test/solidity_dynamic_strings.js
Outdated
contractName, | ||
context.web3 | ||
); | ||
context.instance = context.contractArtifact.instance; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
unless you're using contractArtifact
, I'd drop contractArtifact
altogether and do
const { instance } = await compileAndDeploy( ...
context.instance = instance
^ sweet ES6 destructuringing syntax will pull the instance
field out of the object returned by compileAndDeploy
and assign it to a const variable of the same name.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Great suggestions for overall refactoring efforts.
test/solidity_dynamic_strings.js
Outdated
describe("Solidity variable string length", function() { | ||
const context = setUp(); | ||
it("replacing a long string with a short string", async function() { | ||
let response; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
usually I only defined vars when they're first assigned unless for some unavoidable reason the variable needs to be accessed in a higher-level scope than the one in which it was assigned (which, in general, is a code smell)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Great suggestions for overall refactoring efforts.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The actual test logic looks fine, but I'd recommend the following
- Squash commits
- Get rid of SetUp method
- Don't set a block time (aka use instamining instead)
- Don't specify a mnemonic (your test doesn't need deterministic accounts)
- Add a test which is evaluated in the EVM
On the last one, I'd write another contract which actually checks the string assignment itself, and reverts if things go wrong. That is, it's possible that this is a bug in the EVM, and the final transaction state is fine, but during execution things are messed up.
Created a setup file for prepping test environments.
Added string validation at the EVM level
…a shorter string with setters Added support for basic multicontract compile and deployments Added string validation at the EVM level
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM! The only real concern I have is with the tests that may have been removed accidentally.
const contractSources = selectedContracts.map((contractName) => { | ||
return { [`${contractName}.sol`]: readFileSync(`${contractPath}${contractName}.sol`, "utf8") }; | ||
}); | ||
const sources = Object.assign(...contractSources); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm not sure we need this line here since this is the last usage of contractSources
. If we do need a copy (in case compile
mutates sources
on line 19) I would change this to explicitly use an empty object as the target
parameter Object.assign({}, ...contractSources)
or just the spread operator like const sources = {...contractSources}
and use the original contractSources
in the return on line 40.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Agreed. Wanted to keep the code readable.
@@ -505,22 +505,6 @@ const tests = function(web3) { | |||
}); | |||
}); | |||
|
|||
describe("eth_getTransactionReceipt", function() { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This may be some squashing magic gone wrong
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This was definitely from me
@@ -661,11 +645,6 @@ const tests = function(web3) { | |||
assert(receipt.contractAddress, "should have deployed a contract"); | |||
}); | |||
|
|||
it("should return null for the to field due to contract creation (eth_getTransactionReceipt)", async function() { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Same as above ^ this may have been removed by accident from PR 212?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This may be some squashing magic gone wrong
let response = await instance.methods.testString().call(); | ||
assert.strictEqual(response, text); | ||
|
||
// Set and confirm (within the EVM) a long string setting to a public variable |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
short* string
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Are you suggesting to rename the variable? testString
is being used to store a long string followed by a short string.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Simple fix 👍
@@ -0,0 +1,51 @@ | |||
const assert = require("assert"); | |||
const pretest = require("./helpers/pretest_setup"); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We can destructure setup
here.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I was opting for readability on this one. Fortunately this is the only export in pretest_setup for now.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'll just rename setup
to some thing more descriptive. 👍
Going to create a new PR open with a cleaner branch. |
Unable to confirm reported bug.