-
Notifications
You must be signed in to change notification settings - Fork 5.8k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Replace Boost-based Natspec test case with one derived from SyntaxTest
#14506
Conversation
SyntaxTest
Oh wow, how long did this take to move from cpp to isoltest? 🚀 |
5e232ea
to
3bdc92f
Compare
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 one and return_param_amount_differs.sol
were originally in syntaxTests/natspec/invalid/
, even though they work just fine. The number of return parameters does not differ like the name implies and perhaps it should. Need to investigate.
If you mean moving the test cases, not much. I spent a few hours writing a test parser. Later I ran it and it did all the work for me (see #14433 (comment)). That was actually the easiest part :) I spent more trying to actually reuse isoltest base classes. I went through a few dead ends in the process. Still, it wasn't by itself that hard and I was actually sitting on this being 90% finished, and waiting for my other refactors to go in. Then it turned out that this last 10% is more annyoing than expected and some features I needed for one more complex test case could not be easily reused. So before the weekend I rewrote the test case on top of |
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 go over the SolidityNatspecJSON.cpp
to double check whether you've moved all of the tests, but that will take some time unfortunately.
)); | ||
|
||
startPosition += 2; | ||
if (startPosition < _line.size() && _line[startPosition] == ' ') |
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.
Should this behave as a trim
function, or do we always expect a maximum of one whitespace 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.
No, I intentionally only strip //
. If there's more indentation there, it's a part of the value. In many cases it won't matter, but in some it might. I'm considering moving this helper to some more general location later, so better not to assume that. Actually, even with JSON it might matter if the parser allows multi-line strings (which I think jsoncpp does). And if you want to print the extracted value, it may look weird without whitespace.
// ---- | ||
// ---- |
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.
Why are there two of these?
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.
That's the feature I added in #14505. CommonSyntaxTest
now supports extra expectations after the error list and these are separated with an extra // ----
. The base class stops reading from the stream there and the derived class can continue, interpreting the content any way it wants.
NatspecJSONTest
interprets it as Natspec JSON. It does it inside parseCustomExpectations()
, which is virtual and provided specifically so that the derived class can put such a logic there. We it could do this already in constructor, like CommonSyntaxTest
does, though I don't really like that mechanism - it's too implicit and I feel like it would be too easy to mess up the order.
I could have used any other separator, but reusing this one seemed logical. The only downside is that we have two when the error section is empty. On the other hand, I don't have to worry about inventing a new one and making sure it's not used for something else.
// "kind": "user", | ||
// "methods": {}, | ||
// "version": 1 |
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.
By the way, we could filter out kind
and version
to make the expectations a little shorter. Should we? version
is the same for all tests and kind
is redundant.
The original tests were inconsistent about it. Some had these fields, but many did not, because the Boost test case allowed omitting them. The downside was that they were not checked, even if included - I actually find one or two places where we were expecting the wrong value. Checking them does not add all that much value though.
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'd keep them.
80511e8
to
f4146ee
Compare
a8cd268
to
a6e703b
Compare
5fa0993
to
bf0d51d
Compare
a6e703b
to
7fc81d0
Compare
bf0d51d
to
7768f26
Compare
7fc81d0
to
ae25418
Compare
7768f26
to
e847596
Compare
ae25418
to
f29ac54
Compare
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 manually checked that all tests from SolidityNatspecJSON.cpp
were transferred.
f29ac54
to
2674048
Compare
2674048
to
9ed96d4
Compare
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.
So, the main portion of the review I've done locally - i.e. playing around with the tests to see whether it's detecting failures properly, and indeed it does.
The comments I left are really more out of curiosity than anything else. I think it's perfectly fine to merge this as soon as the osx
jobs are fixed, i.e. no point in waiting much further.
case NatspecJSONKind::Devdoc: _output << "devdoc"; break; | ||
case NatspecJSONKind::Userdoc: _output << "userdoc"; break; |
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.
You don't indent cases inside a switch statement? Is that our style?
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.
Yes. I actually don't like that style too much (I'd prefer the cases
to be indented one level), but I stick to it because that's the style used around the code base.
// sometimes uint and they compare as different even when both are 1. | ||
return | ||
SyntaxTest::expectationsMatch() && | ||
prettyPrinted(obtainedNatspec()) == prettyPrinted(m_expectedNatspecJSON); |
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.
obtainedNatspec()
returns both devdoc and userdoc for requested contracts, and many tests only expect either userdoc or devdoc; how does this comparison work?
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.
many tests only expect either userdoc or devdoc
It used to be the case in the boost tests but if you look at the new expectations, they now always have both userdoc and devdoc.
See commit e702640 (natspecJSON: Generate missing expectations (including errors)
), which adds those expectations (auto-generated by isoltest).
output += "\n\n"; | ||
first = false; | ||
|
||
output += contractName + " " + toString(jsonKind) + "\n"; |
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.
Multisource tests also include the file name, e.g. Testfile.sol:Token devdoc
, so where does said filename and :
delimiter come from? Is it inherited from SyntaxTest
?
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.
That's the fully-qualified contract name. It comes from compiler().contractNames()
and it's what all of its functions expect when the parameter is a contract name. That's how CompilerStack
refers to contracts.
…nversion - Expectation order matching the order of contracts in the source - Typos in test names - Redundant prefixes in test names - Wrong 'king' in some expectations (it's not checked by the test suite)
…ot be handled correctly by the script - dev_multiple_params_mixed_whitespace has whitespace that is not completely preserved - dev_explicit_inherit_complex is a multi-file test
9ed96d4
to
b63a940
Compare
Fixes #14433.
Depends on #14505.
I recommend reviewing commits individually in this PR. There's a lot of file moves and simple changes that can be easily skimmed, but this is not apparent in the unified diff.