/src/solidity/test/TestCaseReader.h
Line | Count | Source (jump to first uncovered line) |
1 | | /* |
2 | | This file is part of solidity. |
3 | | |
4 | | solidity is free software: you can redistribute it and/or modify |
5 | | it under the terms of the GNU General Public License as published by |
6 | | the Free Software Foundation, either version 3 of the License, or |
7 | | (at your option) any later version. |
8 | | |
9 | | solidity is distributed in the hope that it will be useful, |
10 | | but WITHOUT ANY WARRANTY; without even the implied warranty of |
11 | | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
12 | | GNU General Public License for more details. |
13 | | |
14 | | You should have received a copy of the GNU General Public License |
15 | | along with solidity. If not, see <http://www.gnu.org/licenses/>. |
16 | | */ |
17 | | // SPDX-License-Identifier: GPL-3.0 |
18 | | |
19 | | #pragma once |
20 | | |
21 | | #include <test/libsolidity/util/SoltestErrors.h> |
22 | | |
23 | | #include <libsolutil/StringUtils.h> |
24 | | |
25 | | #include <range/v3/view/map.hpp> |
26 | | |
27 | | #include <boost/filesystem.hpp> |
28 | | #include <boost/throw_exception.hpp> |
29 | | |
30 | | #include <fstream> |
31 | | #include <map> |
32 | | #include <string> |
33 | | |
34 | | namespace solidity::frontend::test |
35 | | { |
36 | | |
37 | | /** |
38 | | * A map for registering source names that also contains the main source name in a test case. |
39 | | */ |
40 | | struct SourceMap |
41 | | { |
42 | | std::map<std::string, std::string> sources; |
43 | | std::map<std::string, boost::filesystem::path> externalSources; |
44 | | std::string mainSourceFile; |
45 | | }; |
46 | | |
47 | | /** |
48 | | * A reader for test case data file, which parses source, settings and (optionally) simple expectations. |
49 | | */ |
50 | | class TestCaseReader |
51 | | { |
52 | | public: |
53 | | TestCaseReader() = default; |
54 | | explicit TestCaseReader(std::string const& _filename); |
55 | | explicit TestCaseReader(std::istringstream const& _testCode); |
56 | | |
57 | 13.7k | SourceMap const& sources() const { return m_sources; } |
58 | | std::string const& source() const; |
59 | 0 | std::size_t lineNumber() const { return m_lineNumber; } |
60 | 13.7k | std::map<std::string, std::string> const& settings() const { return m_settings; } |
61 | 0 | std::ifstream& stream() { return m_fileStream; } |
62 | | |
63 | | std::string simpleExpectations(); |
64 | | |
65 | | bool boolSetting(std::string const& _name, bool _defaultValue); |
66 | | size_t sizetSetting(std::string const& _name, size_t _defaultValue); |
67 | | std::string stringSetting(std::string const& _name, std::string const& _defaultValue); |
68 | | |
69 | | template <typename E> |
70 | | E enumSetting(std::string const& _name, std::map<std::string, E> const& _choices, std::string const& _defaultChoice); |
71 | | |
72 | | void ensureAllSettingsRead() const; |
73 | | |
74 | | private: |
75 | | std::pair<SourceMap, std::size_t> parseSourcesAndSettingsWithLineNumber(std::istream& _file); |
76 | | static std::string parseSimpleExpectations(std::istream& _file); |
77 | | |
78 | | std::ifstream m_fileStream; |
79 | | boost::filesystem::path m_fileName; |
80 | | SourceMap m_sources; |
81 | | std::size_t m_lineNumber = 0; |
82 | | std::map<std::string, std::string> m_settings; |
83 | | std::map<std::string, std::string> m_unreadSettings; ///< tracks which settings are left unread |
84 | | }; |
85 | | |
86 | | template <typename E> |
87 | | E TestCaseReader::enumSetting(std::string const& _name, std::map<std::string, E> const& _choices, std::string const& _defaultChoice) |
88 | | { |
89 | | soltestAssert(_choices.count(_defaultChoice) > 0, ""); |
90 | | |
91 | | std::string value = stringSetting(_name, _defaultChoice); |
92 | | |
93 | | if (_choices.count(value) == 0) |
94 | | BOOST_THROW_EXCEPTION(std::runtime_error( |
95 | | "Invalid Enum value: " + value + ". Available choices: " + util::joinHumanReadable(_choices | ranges::views::keys) + "." |
96 | | )); |
97 | | |
98 | | return _choices.at(value); |
99 | | } |
100 | | |
101 | | } |