Merge pull request #9681 from ethereum/small-astjsontest-refactor

Refactor ASTJSONTest to reduce redundancy
This commit is contained in:
chriseth 2020-08-31 19:50:06 +02:00 committed by GitHub
commit b3b1df6556
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 243 additions and 89 deletions

View File

@ -1,3 +1,124 @@
[
{
"attributes":
{
"absolutePath": "a",
"exportedSymbols":
{
"C":
[
2
]
}
},
"children":
[
{
"attributes":
{
"abstract": false,
"baseContracts":
[
null
],
"contractDependencies":
[
null
],
"contractKind": "contract",
"fullyImplemented": true,
"linearizedBaseContracts":
[
2
],
"name": "C",
"nodes":
[
null
],
"scope": 3
},
"children":
[
{
"attributes":
{
"text": "This contract is empty"
},
"id": 1,
"name": "StructuredDocumentation",
"src": "0:27:1"
}
],
"id": 2,
"name": "ContractDefinition",
"src": "28:13:1"
}
],
"id": 3,
"name": "SourceUnit",
"src": "28:14:1"
},
{
"attributes":
{
"absolutePath": "b",
"exportedSymbols":
{
"C":
[
5
]
}
},
"children":
[
{
"attributes":
{
"abstract": false,
"baseContracts":
[
null
],
"contractDependencies":
[
null
],
"contractKind": "contract",
"fullyImplemented": true,
"linearizedBaseContracts":
[
5
],
"name": "C",
"nodes":
[
null
],
"scope": 6
},
"children":
[
{
"attributes":
{
"text": "This contract is empty\nand has a line-breaking comment."
},
"id": 4,
"name": "StructuredDocumentation",
"src": "0:61:2"
}
],
"id": 5,
"name": "ContractDefinition",
"src": "62:13:2"
}
],
"id": 6,
"name": "SourceUnit",
"src": "62:14:2"
},
{ {
"attributes": "attributes":
{ {
@ -240,3 +361,4 @@
"name": "SourceUnit", "name": "SourceUnit",
"src": "0:214:3" "src": "0:214:3"
} }
]

View File

@ -131,9 +131,8 @@ TestCase::TestResult ASTJSONTest::run(ostream& _stream, string const& _linePrefi
} }
c.setSources(sources); c.setSources(sources);
c.setEVMVersion(solidity::test::CommonOptions::get().evmVersion()); c.setEVMVersion(solidity::test::CommonOptions::get().evmVersion());
if (c.parse())
c.analyze(); if (!c.parse())
else
{ {
SourceReferenceFormatterHuman formatter(_stream, _formatted, false); SourceReferenceFormatterHuman formatter(_stream, _formatted, false);
for (auto const& error: c.errors()) for (auto const& error: c.errors())
@ -141,85 +140,99 @@ TestCase::TestResult ASTJSONTest::run(ostream& _stream, string const& _linePrefi
return TestResult::FatalError; return TestResult::FatalError;
} }
if (m_sources.size() > 1) c.analyze();
m_result += "[\n";
for (size_t i = 0; i < m_sources.size(); i++) bool resultsMatch = runTest(
{ m_expectation,
ostringstream result; m_result,
ASTJsonConverter(false, sourceIndices).print(result, c.ast(m_sources[i].first)); sourceIndices,
m_result += result.str(); c,
if (i != m_sources.size() - 1) false,
m_result += ","; "",
m_result += "\n"; _stream,
} _linePrefix,
_formatted
);
if (m_sources.size() > 1) resultsMatch = runTest(
m_result += "]\n"; m_expectationLegacy,
m_resultLegacy,
bool resultsMatch = true; sourceIndices,
c,
replaceTagWithVersion(m_expectation); true,
"legacy",
if (m_expectation != m_result) _stream,
{ _linePrefix,
string nextIndentLevel = _linePrefix + " "; _formatted
AnsiColorized(_stream, _formatted, {BOLD, CYAN}) << _linePrefix << "Expected result:" << endl; ) && resultsMatch;
{
istringstream stream(m_expectation);
string line;
while (getline(stream, line))
_stream << nextIndentLevel << line << endl;
}
_stream << endl;
AnsiColorized(_stream, _formatted, {BOLD, CYAN}) << _linePrefix << "Obtained result:" << endl;
{
istringstream stream(m_result);
string line;
while (getline(stream, line))
_stream << nextIndentLevel << line << endl;
}
_stream << endl;
resultsMatch = false;
}
for (size_t i = 0; i < m_sources.size(); i++)
{
ostringstream result;
ASTJsonConverter(true, sourceIndices).print(result, c.ast(m_sources[i].first));
m_resultLegacy = result.str();
if (i != m_sources.size() - 1)
m_resultLegacy += ",";
m_resultLegacy += "\n";
}
replaceTagWithVersion(m_expectationLegacy);
if (m_expectationLegacy != m_resultLegacy)
{
string nextIndentLevel = _linePrefix + " ";
AnsiColorized(_stream, _formatted, {BOLD, CYAN}) << _linePrefix << "Expected result (legacy):" << endl;
{
istringstream stream(m_expectationLegacy);
string line;
while (getline(stream, line))
_stream << nextIndentLevel << line << endl;
}
_stream << endl;
AnsiColorized(_stream, _formatted, {BOLD, CYAN}) << _linePrefix << "Obtained result (legacy):" << endl;
{
istringstream stream(m_resultLegacy);
string line;
while (getline(stream, line))
_stream << nextIndentLevel << line << endl;
}
_stream << endl;
resultsMatch = false;
}
return resultsMatch ? TestResult::Success : TestResult::Failure; return resultsMatch ? TestResult::Success : TestResult::Failure;
} }
bool ASTJSONTest::runTest(
string& _expectation,
string& _result,
map<string, unsigned> const& _sourceIndices,
CompilerStack& _compiler,
bool _legacy,
string const& _variation,
ostream& _stream,
string const& _linePrefix,
bool const _formatted
)
{
if (m_sources.size() > 1)
_result += "[\n";
for (size_t i = 0; i < m_sources.size(); i++)
{
ostringstream result;
ASTJsonConverter(_legacy, _sourceIndices).print(result, _compiler.ast(m_sources[i].first));
_result += result.str();
if (i != m_sources.size() - 1)
_result += ",";
_result += "\n";
}
if (m_sources.size() > 1)
_result += "]\n";
replaceTagWithVersion(_expectation);
if (_expectation != _result)
{
string nextIndentLevel = _linePrefix + " ";
AnsiColorized(_stream, _formatted, {BOLD, CYAN}) <<
_linePrefix <<
"Expected result" <<
(!_variation.empty() ? " (" + _variation + "):" : ":") <<
endl;
{
istringstream stream(_expectation);
string line;
while (getline(stream, line))
_stream << nextIndentLevel << line << endl;
}
_stream << endl;
AnsiColorized(_stream, _formatted, {BOLD, CYAN}) <<
_linePrefix <<
"Obtained result" <<
(!_variation.empty() ? " (" + _variation + "):" : ":") <<
endl;
{
istringstream stream(_result);
string line;
while (getline(stream, line))
_stream << nextIndentLevel << line << endl;
}
_stream << endl;
return false;
}
return true;;
}
void ASTJSONTest::printSource(ostream& _stream, string const& _linePrefix, bool const) const void ASTJSONTest::printSource(ostream& _stream, string const& _linePrefix, bool const) const
{ {
for (auto const& source: m_sources) for (auto const& source: m_sources)
@ -236,24 +249,20 @@ void ASTJSONTest::printSource(ostream& _stream, string const& _linePrefix, bool
void ASTJSONTest::printUpdatedExpectations(std::ostream&, std::string const&) const void ASTJSONTest::printUpdatedExpectations(std::ostream&, std::string const&) const
{ {
ofstream file(m_astFilename.c_str()); updateExpectation(m_astFilename, m_result, "");
if (!file) BOOST_THROW_EXCEPTION(runtime_error("Cannot write AST expectation to \"" + m_astFilename + "\".")); updateExpectation(m_legacyAstFilename, m_resultLegacy, "legacy ");
}
void ASTJSONTest::updateExpectation(string const& _filename, string const& _expectation, string const& _variation) const
{
ofstream file(_filename.c_str());
if (!file) BOOST_THROW_EXCEPTION(runtime_error("Cannot write " + _variation + "AST expectation to \"" + _filename + "\"."));
file.exceptions(ios::badbit); file.exceptions(ios::badbit);
string replacedResult = m_result; string replacedResult = _expectation;
replaceVersionWithTag(replacedResult); replaceVersionWithTag(replacedResult);
file << replacedResult; file << replacedResult;
file.flush(); file.flush();
file.close(); file.close();
file.open(m_legacyAstFilename.c_str());
if (!file) BOOST_THROW_EXCEPTION(runtime_error("Cannot write legacy AST expectation to \"" + m_legacyAstFilename + "\"."));
string replacedResultLegacy = m_resultLegacy;
replaceVersionWithTag(replacedResultLegacy);
file << replacedResultLegacy;
file.flush();
file.close();
} }

View File

@ -26,9 +26,15 @@
#include <vector> #include <vector>
#include <utility> #include <utility>
namespace solidity::frontend
{
class CompilerStack;
}
namespace solidity::frontend::test namespace solidity::frontend::test
{ {
class ASTJSONTest: public TestCase class ASTJSONTest: public TestCase
{ {
public: public:
@ -41,6 +47,23 @@ public:
void printSource(std::ostream& _stream, std::string const& _linePrefix = "", bool const _formatted = false) const override; void printSource(std::ostream& _stream, std::string const& _linePrefix = "", bool const _formatted = false) const override;
void printUpdatedExpectations(std::ostream& _stream, std::string const& _linePrefix) const override; void printUpdatedExpectations(std::ostream& _stream, std::string const& _linePrefix) const override;
private: private:
bool runTest(
std::string& _expectation,
std::string& _result,
std::map<std::string, unsigned> const& _sourceIndicies,
CompilerStack& _compiler,
bool _legacy,
std::string const& _variation,
std::ostream& _stream,
std::string const& _linePrefix = "",
bool const _formatted = false
);
void updateExpectation(
std::string const& _filename,
std::string const& _expectation,
std::string const& _variation
) const;
std::vector<std::pair<std::string, std::string>> m_sources; std::vector<std::pair<std::string, std::string>> m_sources;
std::string m_expectationLegacy; std::string m_expectationLegacy;
std::string m_astFilename; std::string m_astFilename;