mirror of
https://github.com/ethereum/solidity
synced 2023-10-03 13:03:40 +00:00
CommonSyntaxTest: Add support for syntax tests with custom expectations in addition to expected errors
This commit is contained in:
parent
c965d6332c
commit
e847596e39
@ -19,6 +19,7 @@
|
|||||||
#include <test/CommonSyntaxTest.h>
|
#include <test/CommonSyntaxTest.h>
|
||||||
#include <test/Common.h>
|
#include <test/Common.h>
|
||||||
#include <test/TestCase.h>
|
#include <test/TestCase.h>
|
||||||
|
#include <libsolutil/CommonIO.h>
|
||||||
#include <boost/algorithm/string.hpp>
|
#include <boost/algorithm/string.hpp>
|
||||||
#include <boost/algorithm/string/predicate.hpp>
|
#include <boost/algorithm/string/predicate.hpp>
|
||||||
#include <boost/test/unit_test.hpp>
|
#include <boost/test/unit_test.hpp>
|
||||||
@ -29,6 +30,7 @@
|
|||||||
|
|
||||||
using namespace std;
|
using namespace std;
|
||||||
using namespace solidity;
|
using namespace solidity;
|
||||||
|
using namespace solidity::util;
|
||||||
using namespace solidity::util::formatting;
|
using namespace solidity::util::formatting;
|
||||||
using namespace solidity::langutil;
|
using namespace solidity::langutil;
|
||||||
using namespace solidity::frontend;
|
using namespace solidity::frontend;
|
||||||
@ -66,6 +68,7 @@ CommonSyntaxTest::CommonSyntaxTest(string const& _filename, langutil::EVMVersion
|
|||||||
|
|
||||||
TestCase::TestResult CommonSyntaxTest::run(ostream& _stream, string const& _linePrefix, bool _formatted)
|
TestCase::TestResult CommonSyntaxTest::run(ostream& _stream, string const& _linePrefix, bool _formatted)
|
||||||
{
|
{
|
||||||
|
parseCustomExpectations(m_reader.stream());
|
||||||
parseAndAnalyze();
|
parseAndAnalyze();
|
||||||
|
|
||||||
return conclude(_stream, _linePrefix, _formatted);
|
return conclude(_stream, _linePrefix, _formatted);
|
||||||
@ -73,7 +76,7 @@ TestCase::TestResult CommonSyntaxTest::run(ostream& _stream, string const& _line
|
|||||||
|
|
||||||
TestCase::TestResult CommonSyntaxTest::conclude(ostream& _stream, string const& _linePrefix, bool _formatted)
|
TestCase::TestResult CommonSyntaxTest::conclude(ostream& _stream, string const& _linePrefix, bool _formatted)
|
||||||
{
|
{
|
||||||
if (m_expectations == m_errorList)
|
if (expectationsMatch())
|
||||||
return TestResult::Success;
|
return TestResult::Success;
|
||||||
|
|
||||||
printExpectationAndError(_stream, _linePrefix, _formatted);
|
printExpectationAndError(_stream, _linePrefix, _formatted);
|
||||||
@ -84,9 +87,9 @@ void CommonSyntaxTest::printExpectationAndError(ostream& _stream, string const&
|
|||||||
{
|
{
|
||||||
string nextIndentLevel = _linePrefix + " ";
|
string nextIndentLevel = _linePrefix + " ";
|
||||||
util::AnsiColorized(_stream, _formatted, {BOLD, CYAN}) << _linePrefix << "Expected result:" << endl;
|
util::AnsiColorized(_stream, _formatted, {BOLD, CYAN}) << _linePrefix << "Expected result:" << endl;
|
||||||
printErrorList(_stream, m_expectations, nextIndentLevel, _formatted);
|
printExpectedResult(_stream, nextIndentLevel, _formatted);
|
||||||
util::AnsiColorized(_stream, _formatted, {BOLD, CYAN}) << _linePrefix << "Obtained result:" << endl;
|
util::AnsiColorized(_stream, _formatted, {BOLD, CYAN}) << _linePrefix << "Obtained result:" << endl;
|
||||||
printErrorList(_stream, m_errorList, nextIndentLevel, _formatted);
|
printObtainedResult(_stream, nextIndentLevel, _formatted);
|
||||||
}
|
}
|
||||||
|
|
||||||
void CommonSyntaxTest::printSource(ostream& _stream, string const& _linePrefix, bool _formatted) const
|
void CommonSyntaxTest::printSource(ostream& _stream, string const& _linePrefix, bool _formatted) const
|
||||||
@ -149,6 +152,30 @@ void CommonSyntaxTest::printSource(ostream& _stream, string const& _linePrefix,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void CommonSyntaxTest::parseCustomExpectations(istream& _stream)
|
||||||
|
{
|
||||||
|
string remainingExpectations = boost::trim_copy(readUntilEnd(_stream));
|
||||||
|
soltestAssert(
|
||||||
|
remainingExpectations.empty(),
|
||||||
|
"Found custom expectations not supported by the test case:\n" + remainingExpectations
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool CommonSyntaxTest::expectationsMatch()
|
||||||
|
{
|
||||||
|
return m_expectations == m_errorList;
|
||||||
|
}
|
||||||
|
|
||||||
|
void CommonSyntaxTest::printExpectedResult(ostream& _stream, string const& _linePrefix, bool _formatted) const
|
||||||
|
{
|
||||||
|
printErrorList(_stream, m_expectations, _linePrefix, _formatted);
|
||||||
|
}
|
||||||
|
|
||||||
|
void CommonSyntaxTest::printObtainedResult(ostream& _stream, string const& _linePrefix, bool _formatted) const
|
||||||
|
{
|
||||||
|
printErrorList(_stream, m_errorList, _linePrefix, _formatted);
|
||||||
|
}
|
||||||
|
|
||||||
void CommonSyntaxTest::printErrorList(
|
void CommonSyntaxTest::printErrorList(
|
||||||
ostream& _stream,
|
ostream& _stream,
|
||||||
vector<SyntaxTestError> const& _errorList,
|
vector<SyntaxTestError> const& _errorList,
|
||||||
@ -157,7 +184,10 @@ void CommonSyntaxTest::printErrorList(
|
|||||||
)
|
)
|
||||||
{
|
{
|
||||||
if (_errorList.empty())
|
if (_errorList.empty())
|
||||||
|
{
|
||||||
|
if (_formatted)
|
||||||
util::AnsiColorized(_stream, _formatted, {BOLD, GREEN}) << _linePrefix << "Success" << endl;
|
util::AnsiColorized(_stream, _formatted, {BOLD, GREEN}) << _linePrefix << "Success" << endl;
|
||||||
|
}
|
||||||
else
|
else
|
||||||
for (auto const& error: _errorList)
|
for (auto const& error: _errorList)
|
||||||
{
|
{
|
||||||
@ -194,12 +224,20 @@ string CommonSyntaxTest::errorMessage(util::Exception const& _e)
|
|||||||
|
|
||||||
vector<SyntaxTestError> CommonSyntaxTest::parseExpectations(istream& _stream)
|
vector<SyntaxTestError> CommonSyntaxTest::parseExpectations(istream& _stream)
|
||||||
{
|
{
|
||||||
|
static string const customExpectationsDelimiter("// ----");
|
||||||
|
|
||||||
vector<SyntaxTestError> expectations;
|
vector<SyntaxTestError> expectations;
|
||||||
string line;
|
string line;
|
||||||
while (getline(_stream, line))
|
while (getline(_stream, line))
|
||||||
{
|
{
|
||||||
auto it = line.begin();
|
auto it = line.begin();
|
||||||
|
|
||||||
|
// Anything below the delimiter is left up to the derived class to process in a custom way.
|
||||||
|
// The delimiter is optional and identical to the one that starts error expectations in
|
||||||
|
// TestCaseReader::parseSourcesAndSettingsWithLineNumber().
|
||||||
|
if (boost::algorithm::starts_with(line, customExpectationsDelimiter))
|
||||||
|
break;
|
||||||
|
|
||||||
skipSlashes(it, line.end());
|
skipSlashes(it, line.end());
|
||||||
skipWhitespace(it, line.end());
|
skipWhitespace(it, line.end());
|
||||||
|
|
||||||
|
@ -62,14 +62,27 @@ public:
|
|||||||
void printSource(std::ostream& _stream, std::string const &_linePrefix = "", bool _formatted = false) const override;
|
void printSource(std::ostream& _stream, std::string const &_linePrefix = "", bool _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
|
||||||
{
|
{
|
||||||
if (!m_errorList.empty())
|
printObtainedResult(_stream, _linePrefix, false);
|
||||||
printErrorList(_stream, m_errorList, _linePrefix, false);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static std::string errorMessage(util::Exception const& _e);
|
static std::string errorMessage(util::Exception const& _e);
|
||||||
protected:
|
protected:
|
||||||
|
/// Should be implemented by those derived test cases that want to allow extra expectations
|
||||||
|
/// after the error/warning expectations. The default implementation does not allow them and
|
||||||
|
/// fails instead.
|
||||||
|
/// @param _stream Input stream positioned at the beginning of the extra expectations.
|
||||||
|
virtual void parseCustomExpectations(std::istream& _stream);
|
||||||
|
|
||||||
virtual void parseAndAnalyze() = 0;
|
virtual void parseAndAnalyze() = 0;
|
||||||
|
|
||||||
|
/// Should return true if obtained values match expectations.
|
||||||
|
/// The default implementation only compares the error list. Derived classes that support
|
||||||
|
/// custom expectations should override this to include them in the comparison.
|
||||||
|
virtual bool expectationsMatch();
|
||||||
|
|
||||||
|
virtual void printExpectedResult(std::ostream& _stream, std::string const& _linePrefix, bool _formatted) const;
|
||||||
|
virtual void printObtainedResult(std::ostream& _stream, std::string const& _linePrefix, bool _formatted) const;
|
||||||
|
|
||||||
static void printErrorList(
|
static void printErrorList(
|
||||||
std::ostream& _stream,
|
std::ostream& _stream,
|
||||||
std::vector<SyntaxTestError> const& _errors,
|
std::vector<SyntaxTestError> const& _errors,
|
||||||
|
@ -114,15 +114,17 @@ pair<SourceMap, size_t> TestCaseReader::parseSourcesAndSettingsWithLineNumber(is
|
|||||||
static string const sourceDelimiterEnd("====");
|
static string const sourceDelimiterEnd("====");
|
||||||
static string const comment("// ");
|
static string const comment("// ");
|
||||||
static string const settingsDelimiter("// ====");
|
static string const settingsDelimiter("// ====");
|
||||||
static string const delimiter("// ----");
|
static string const expectationsDelimiter("// ----");
|
||||||
bool sourcePart = true;
|
bool sourcePart = true;
|
||||||
while (getline(_stream, line))
|
while (getline(_stream, line))
|
||||||
{
|
{
|
||||||
lineNumber++;
|
lineNumber++;
|
||||||
|
|
||||||
if (boost::algorithm::starts_with(line, delimiter))
|
// Anything below the delimiter is left up to the test case to process in a custom way.
|
||||||
|
if (boost::algorithm::starts_with(line, expectationsDelimiter))
|
||||||
break;
|
break;
|
||||||
else if (boost::algorithm::starts_with(line, settingsDelimiter))
|
|
||||||
|
if (boost::algorithm::starts_with(line, settingsDelimiter))
|
||||||
sourcePart = false;
|
sourcePart = false;
|
||||||
else if (sourcePart)
|
else if (sourcePart)
|
||||||
{
|
{
|
||||||
|
Loading…
Reference in New Issue
Block a user