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":
{
@ -240,3 +361,4 @@
"name": "SourceUnit",
"src": "0:214:3"
}
]

View File

@ -131,9 +131,8 @@ TestCase::TestResult ASTJSONTest::run(ostream& _stream, string const& _linePrefi
}
c.setSources(sources);
c.setEVMVersion(solidity::test::CommonOptions::get().evmVersion());
if (c.parse())
c.analyze();
else
if (!c.parse())
{
SourceReferenceFormatterHuman formatter(_stream, _formatted, false);
for (auto const& error: c.errors())
@ -141,85 +140,99 @@ TestCase::TestResult ASTJSONTest::run(ostream& _stream, string const& _linePrefi
return TestResult::FatalError;
}
if (m_sources.size() > 1)
m_result += "[\n";
c.analyze();
for (size_t i = 0; i < m_sources.size(); i++)
{
ostringstream result;
ASTJsonConverter(false, sourceIndices).print(result, c.ast(m_sources[i].first));
m_result += result.str();
if (i != m_sources.size() - 1)
m_result += ",";
m_result += "\n";
}
bool resultsMatch = runTest(
m_expectation,
m_result,
sourceIndices,
c,
false,
"",
_stream,
_linePrefix,
_formatted
);
if (m_sources.size() > 1)
m_result += "]\n";
bool resultsMatch = true;
replaceTagWithVersion(m_expectation);
if (m_expectation != m_result)
{
string nextIndentLevel = _linePrefix + " ";
AnsiColorized(_stream, _formatted, {BOLD, CYAN}) << _linePrefix << "Expected result:" << endl;
{
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;
}
resultsMatch = runTest(
m_expectationLegacy,
m_resultLegacy,
sourceIndices,
c,
true,
"legacy",
_stream,
_linePrefix,
_formatted
) && resultsMatch;
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
{
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
{
ofstream file(m_astFilename.c_str());
if (!file) BOOST_THROW_EXCEPTION(runtime_error("Cannot write AST expectation to \"" + m_astFilename + "\"."));
updateExpectation(m_astFilename, m_result, "");
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);
string replacedResult = m_result;
string replacedResult = _expectation;
replaceVersionWithTag(replacedResult);
file << replacedResult;
file.flush();
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 <utility>
namespace solidity::frontend
{
class CompilerStack;
}
namespace solidity::frontend::test
{
class ASTJSONTest: public TestCase
{
public:
@ -41,6 +47,23 @@ public:
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;
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::string m_expectationLegacy;
std::string m_astFilename;