Skip to content
This repository has been archived by the owner on Feb 26, 2024. It is now read-only.

Issue 678: Testing solidity strings with getters/setters #218

Closed
wants to merge 18 commits into from

Conversation

ccowell
Copy link
Contributor

@ccowell ccowell commented Nov 7, 2018

Unable to confirm reported bug.

@ccowell ccowell requested a review from eshaben November 7, 2018 20:08
Copy link
Contributor

@eshaben eshaben left a 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!

@benjamincburns
Copy link
Contributor

Looks like a lot of commits for relatively small net change - I'd recommend squashing the commits and doing git push -f to keep the change log easier to read


contract DynamicStringLength {
string public testString;
uint public testId = 246;
Copy link
Contributor

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

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good catch.

const path = require("path");
const compileAndDeploy = require("./helpers/contracts").compileAndDeploy;

const mnemonic = "candy maple cake sugar pudding cream honey rich smooth crumble sweet treat";
Copy link
Contributor

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.

Copy link
Contributor Author

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.

}

describe("Solidity variable string length", function() {
const context = setUp();
Copy link
Contributor

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(...
  }
}

Copy link
Contributor Author

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.


before("setup web3", async function() {
context.provider = Ganache.provider(context.options);
context.options.blockTime = 2000;
Copy link
Contributor

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

Copy link
Contributor

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

before("compile source", async function() {
this.timeout(10000);
context.contractArtifact = await compileAndDeploy(
path.join(__dirname, ".", `${contractName}.sol`),
Copy link
Contributor

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

Copy link
Contributor Author

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.

contractName,
context.web3
);
context.instance = context.contractArtifact.instance;
Copy link
Contributor

@benjamincburns benjamincburns Nov 7, 2018

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.

Copy link
Contributor Author

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.

describe("Solidity variable string length", function() {
const context = setUp();
it("replacing a long string with a short string", async function() {
let response;
Copy link
Contributor

@benjamincburns benjamincburns Nov 7, 2018

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)

Copy link
Contributor Author

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.

Copy link
Contributor

@benjamincburns benjamincburns left a 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.

Copy link
Contributor

@nicholasjpaterno nicholasjpaterno left a 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);
Copy link
Contributor

@nicholasjpaterno nicholasjpaterno Nov 13, 2018

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.

Copy link
Contributor Author

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() {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think maybe this was removed by accident? This looks like it was part of @eshaben's commit for PR 212

Copy link
Contributor Author

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

Copy link
Contributor

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() {
Copy link
Contributor

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?

Copy link
Contributor Author

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
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

short* string

Copy link
Contributor Author

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.

Copy link
Contributor Author

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");
Copy link
Contributor

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.

Copy link
Contributor Author

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.

Copy link
Contributor Author

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. 👍

@ccowell
Copy link
Contributor Author

ccowell commented Nov 14, 2018

Going to create a new PR open with a cleaner branch.

@ccowell ccowell closed this Nov 14, 2018
@ccowell ccowell deleted the issue-678 branch November 14, 2018 16:52
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants