diff options
author | Daniel Kirchner <daniel@ekpyron.org> | 2018-03-12 20:57:48 +0800 |
---|---|---|
committer | Daniel Kirchner <daniel@ekpyron.org> | 2018-03-15 23:23:46 +0800 |
commit | 269241e9105a3b3014002bf711ade985d87febe4 (patch) | |
tree | a53423868c010faaa69f9dcc000d34e750a16279 /test/libsolidity | |
parent | 61d9f88c0e826c75fc70dafc7808964dc7a7e1f4 (diff) | |
download | dexon-solidity-269241e9105a3b3014002bf711ade985d87febe4.tar.gz dexon-solidity-269241e9105a3b3014002bf711ade985d87febe4.tar.zst dexon-solidity-269241e9105a3b3014002bf711ade985d87febe4.zip |
Add formatted printing to SyntaxTest and expand its public interface.
Diffstat (limited to 'test/libsolidity')
-rw-r--r-- | test/libsolidity/FormattedScope.h | 66 | ||||
-rw-r--r-- | test/libsolidity/SyntaxTest.cpp | 56 | ||||
-rw-r--r-- | test/libsolidity/SyntaxTest.h | 17 |
3 files changed, 123 insertions, 16 deletions
diff --git a/test/libsolidity/FormattedScope.h b/test/libsolidity/FormattedScope.h new file mode 100644 index 00000000..78560848 --- /dev/null +++ b/test/libsolidity/FormattedScope.h @@ -0,0 +1,66 @@ +/* + This file is part of solidity. + + solidity is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + solidity is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with solidity. If not, see <http://www.gnu.org/licenses/>. +*/ + +#pragma once + +#include <boost/noncopyable.hpp> + +#include <ostream> +#include <vector> + +namespace dev +{ +namespace solidity +{ +namespace test +{ + +namespace formatting +{ + +static constexpr char const* RESET = "\033[0m"; +static constexpr char const* RED = "\033[1;31m"; +static constexpr char const* GREEN = "\033[1;32m"; +static constexpr char const* YELLOW = "\033[1;33m"; +static constexpr char const* CYAN = "\033[1;36m"; +static constexpr char const* BOLD = "\033[1m"; +static constexpr char const* INVERSE = "\033[7m"; + +} + +class FormattedScope: boost::noncopyable +{ +public: + /// @arg _formatting List of formatting strings (e.g. colors) defined in the formatting namespace. + FormattedScope(std::ostream& _stream, bool const _enabled, std::vector<char const*> const& _formatting): + m_stream(_stream), m_enabled(_enabled) + { + if (m_enabled) + for (auto const& format: _formatting) + m_stream << format; + } + ~FormattedScope() { if (m_enabled) m_stream << formatting::RESET; } + template<typename T> + std::ostream& operator<<(T&& _t) { return m_stream << std::forward<T>(_t); } +private: + std::ostream& m_stream; + bool m_enabled; +}; + +} +} +} diff --git a/test/libsolidity/SyntaxTest.cpp b/test/libsolidity/SyntaxTest.cpp index 45a851b6..70abac48 100644 --- a/test/libsolidity/SyntaxTest.cpp +++ b/test/libsolidity/SyntaxTest.cpp @@ -27,6 +27,7 @@ using namespace dev; using namespace solidity; using namespace dev::solidity::test; +using namespace dev::solidity::test::formatting; using namespace std; namespace fs = boost::filesystem; using namespace boost::unit_test; @@ -56,41 +57,70 @@ SyntaxTest::SyntaxTest(string const& _filename) m_expectations = parseExpectations(file); } -bool SyntaxTest::run(ostream& _stream, string const& _indent) +bool SyntaxTest::run(ostream& _stream, string const& _linePrefix, bool const _formatted) { m_errorList = parseAnalyseAndReturnError(m_source, true, true, true).second; if (!matchesExpectations(m_errorList)) { - std::string nextIndentLevel = _indent + "\t"; - _stream << _indent << "Expected result:" << endl; - printExpected(_stream, nextIndentLevel); - _stream << _indent << "Obtained result:\n"; - printErrorList(_stream, m_errorList, nextIndentLevel); + std::string nextIndentLevel = _linePrefix + " "; + FormattedScope(_stream, _formatted, {BOLD, CYAN}) << _linePrefix << "Expected result:" << endl; + printExpected(_stream, nextIndentLevel, _formatted); + FormattedScope(_stream, _formatted, {BOLD, CYAN}) << _linePrefix << "Obtained result:\n"; + printErrorList(_stream, m_errorList, nextIndentLevel, false, false, _formatted); return false; } return true; } -void SyntaxTest::printExpected(ostream& _stream, string const& _indent) const +void SyntaxTest::printExpected(ostream& _stream, string const& _linePrefix, bool const _formatted) const { if (m_expectations.empty()) - _stream << _indent << "Success" << endl; + FormattedScope(_stream, _formatted, {BOLD, GREEN}) << _linePrefix << "Success" << endl; else for (auto const& expectation: m_expectations) - _stream << _indent << expectation.type << ": " << expectation.message << endl; + FormattedScope(_stream, _formatted, {BOLD, expectation.type == "Warning" ? YELLOW : RED}) << + _linePrefix << expectation.type << ": " << expectation.message << endl; } void SyntaxTest::printErrorList( ostream& _stream, ErrorList const& _errorList, - string const& _indent + string const& _linePrefix, + bool const _ignoreWarnings, + bool const _lineNumbers, + bool const _formatted ) const { if (_errorList.empty()) - _stream << _indent << "Success" << endl; + FormattedScope(_stream, _formatted, {BOLD, GREEN}) << _linePrefix << "Success" << endl; else for (auto const& error: _errorList) - _stream << _indent << error->typeName() << ": " << errorMessage(*error) << endl; + { + bool isWarning = (error->type() == Error::Type::Warning); + if (isWarning && _ignoreWarnings) continue; + + FormattedScope scope(_stream, _formatted, {BOLD, isWarning ? YELLOW : RED}); + _stream << _linePrefix; + if (_lineNumbers) + { + int line = offsetToLineNumber( + boost::get_error_info<errinfo_sourceLocation>(*error)->start + ); + if (line >= 0) + _stream << "(" << line << "): "; + } + _stream << error->typeName() << ": " << errorMessage(*error) << endl; + } +} + +int SyntaxTest::offsetToLineNumber(int _location) const +{ + // parseAnalyseAndReturnError(...) prepends a version pragma + _location -= strlen("pragma solidity >=0.0;\n"); + if (_location < 0 || static_cast<size_t>(_location) >= m_source.size()) + return -1; + else + return 1 + std::count(m_source.begin(), m_source.begin() + _location, '\n'); } bool SyntaxTest::matchesExpectations(ErrorList const& _errorList) const @@ -196,7 +226,7 @@ int SyntaxTest::registerTests( [fullpath] { std::stringstream errorStream; - if (!SyntaxTest(fullpath.string()).run(errorStream, "")) + if (!SyntaxTest(fullpath.string()).run(errorStream)) BOOST_ERROR("Test expectation mismatch.\n" + errorStream.str()); }, _path.stem().string(), diff --git a/test/libsolidity/SyntaxTest.h b/test/libsolidity/SyntaxTest.h index 4379c77b..441cc4f8 100644 --- a/test/libsolidity/SyntaxTest.h +++ b/test/libsolidity/SyntaxTest.h @@ -18,6 +18,7 @@ #pragma once #include <test/libsolidity/AnalysisFramework.h> +#include <test/libsolidity/FormattedScope.h> #include <libsolidity/interface/Exceptions.h> #include <boost/noncopyable.hpp> @@ -47,13 +48,22 @@ class SyntaxTest: AnalysisFramework public: SyntaxTest(std::string const& _filename); - bool run(std::ostream& _stream, std::string const& _indent); + bool run(std::ostream& _stream, std::string const& _linePrefix = "", bool const _formatted = false); + + std::vector<SyntaxTestExpectation> const& expectations() const { return m_expectations; } + std::string const& source() const { return m_source; } + ErrorList const& errorList() const { return m_errorList; } + ErrorList const& compilerErrors() const { return m_compiler.errors(); } + + void printExpected(std::ostream& _stream, std::string const& _linePrefix, bool const _formatted = false) const; - void printExpected(std::ostream& _stream, std::string const& _indent) const; void printErrorList( std::ostream& _stream, ErrorList const& _errors, - std::string const& _indent + std::string const& _linePrefix, + bool const _ignoreWarnings, + bool const _lineNumbers, + bool const _formatted = false ) const; static int registerTests( @@ -66,6 +76,7 @@ private: static std::string errorMessage(Error const& _e); static std::string parseSource(std::istream& _stream); static std::vector<SyntaxTestExpectation> parseExpectations(std::istream& _stream); + int offsetToLineNumber(int _location) const; std::string m_source; std::vector<SyntaxTestExpectation> m_expectations; |