Skip to content

Commit 980aaf2

Browse files
committed
Adds unit tests for test file parser.
1 parent 15a5d91 commit 980aaf2

File tree

1 file changed

+228
-0
lines changed

1 file changed

+228
-0
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,228 @@
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+
/**
18+
* Unit tests for Solidity's test expectation parser.
19+
*/
20+
21+
#include <functional>
22+
#include <string>
23+
#include <tuple>
24+
#include <boost/test/unit_test.hpp>
25+
#include <liblangutil/Exceptions.h>
26+
#include <test/libsolidity/SolidityExecutionFramework.h>
27+
28+
#include <test/libsolidity/util/TestFileParser.h>
29+
30+
using namespace std;
31+
using namespace dev::test;
32+
33+
namespace dev
34+
{
35+
namespace solidity
36+
{
37+
namespace test
38+
{
39+
40+
vector<FunctionCall> parse(string const& _source)
41+
{
42+
istringstream stream{_source, ios_base::out};
43+
TestFileParser parser{stream};
44+
return parser.parseFunctionCalls();
45+
}
46+
47+
BOOST_AUTO_TEST_SUITE(TestFileParserTest)
48+
49+
BOOST_AUTO_TEST_CASE(smoke_test)
50+
{
51+
char const* source = R"()";
52+
BOOST_CHECK_EQUAL(parse(source).size(), 0);
53+
}
54+
55+
BOOST_AUTO_TEST_CASE(simple_call_succees)
56+
{
57+
char const* source = R"(
58+
// f()
59+
// -> 1
60+
)";
61+
auto const& calls = parse(source);
62+
BOOST_CHECK_EQUAL(calls.size(), 1);
63+
64+
auto const& call = calls.at(0);
65+
BOOST_CHECK_EQUAL(call.signature, "f()");
66+
BOOST_CHECK_EQUAL(call.expectations.output, "-> 1");
67+
BOOST_CHECK_EQUAL(call.expectations.raw, "1");
68+
}
69+
70+
BOOST_AUTO_TEST_CASE(non_existent_call_revert)
71+
{
72+
char const* source = R"(
73+
// i_am_not_there()
74+
// REVERT
75+
)";
76+
auto const& calls = parse(source);
77+
BOOST_CHECK_EQUAL(calls.size(), 1);
78+
79+
auto const& call = calls.at(0);
80+
BOOST_CHECK_EQUAL(call.signature, "i_am_not_there()");
81+
BOOST_CHECK_EQUAL(call.expectations.output, "REVERT");
82+
BOOST_CHECK_EQUAL(call.expectations.raw, "");
83+
}
84+
85+
BOOST_AUTO_TEST_CASE(call_comments)
86+
{
87+
char const* source = R"(
88+
// f() # This is a comment
89+
// -> 1 # This is another comment
90+
)";
91+
auto const& calls = parse(source);
92+
BOOST_CHECK_EQUAL(calls.size(), 1);
93+
94+
auto const& call = calls.at(0);
95+
BOOST_CHECK_EQUAL(call.signature, "f()");
96+
BOOST_CHECK_EQUAL(call.arguments.comment, "This is a comment");
97+
BOOST_CHECK_EQUAL(call.expectations.output, "-> 1");
98+
BOOST_CHECK_EQUAL(call.expectations.raw, "1");
99+
BOOST_CHECK_EQUAL(call.expectations.comment, "This is another comment");
100+
}
101+
102+
BOOST_AUTO_TEST_CASE(call_arguments)
103+
{
104+
char const* source = R"(
105+
// f(uint256): 5
106+
// : 314 # optional ether value
107+
// -> -4
108+
)";
109+
auto const& calls = parse(source);
110+
BOOST_CHECK_EQUAL(calls.size(), 1);
111+
112+
auto const& call = calls.at(0);
113+
BOOST_CHECK_EQUAL(call.signature, "f(uint256)");
114+
BOOST_CHECK_EQUAL(call.value, u256{314});
115+
BOOST_CHECK_EQUAL(call.arguments.raw, "5");
116+
BOOST_CHECK_EQUAL(call.expectations.output, "-> -4");
117+
BOOST_CHECK_EQUAL(call.expectations.raw, "-4");
118+
ABI_CHECK(call.arguments.rawBytes, toBigEndian(u256{5}));
119+
ABI_CHECK(call.expectations.rawBytes, toBigEndian(u256{-4}));
120+
}
121+
122+
BOOST_AUTO_TEST_CASE(call_expectations_missing)
123+
{
124+
char const* source = R"(
125+
// f())";
126+
BOOST_CHECK_THROW(parse(source), langutil::Error);
127+
}
128+
129+
BOOST_AUTO_TEST_CASE(call_ether_value_expectations_missing)
130+
{
131+
char const* source = R"(
132+
// f()
133+
// : 0)";
134+
BOOST_CHECK_THROW(parse(source), langutil::Error);
135+
}
136+
137+
BOOST_AUTO_TEST_CASE(call_arguments_invalid)
138+
{
139+
char const* source = R"(
140+
// f(uint256): abc
141+
// -> 1
142+
)";
143+
BOOST_CHECK_THROW(parse(source), langutil::Error);
144+
}
145+
146+
BOOST_AUTO_TEST_CASE(call_ether_value_invalid)
147+
{
148+
char const* source = R"(
149+
// f(uint256): 1
150+
// : abc
151+
// -> 1
152+
)";
153+
BOOST_CHECK_THROW(parse(source), langutil::Error);
154+
}
155+
156+
BOOST_AUTO_TEST_CASE(call_arguments_mismatch)
157+
{
158+
char const* source = R"(
159+
// f(uint256, uint256): 1 # This only throws at runtime
160+
// -> 1
161+
)";
162+
auto const& calls = parse(source);
163+
BOOST_CHECK_EQUAL(calls.size(), 1);
164+
165+
auto const& call = calls.at(0);
166+
BOOST_CHECK_EQUAL(call.signature, "f(uint256, uint256)");
167+
BOOST_CHECK_EQUAL(call.arguments.raw, "1");
168+
}
169+
170+
BOOST_AUTO_TEST_CASE(call_multiple_arguments)
171+
{
172+
char const* source = R"(
173+
// f(uint256, uint256): 1, 2
174+
// -> 1, 1
175+
)";
176+
auto const& calls = parse(source);
177+
BOOST_CHECK_EQUAL(calls.size(), 1);
178+
179+
auto const& call = calls.at(0);
180+
BOOST_CHECK_EQUAL(call.signature, "f(uint256, uint256)");
181+
BOOST_CHECK_EQUAL(call.arguments.raw, "1, 2");
182+
ABI_CHECK(call.arguments.rawBytes, toBigEndian(u256{1}) + toBigEndian(u256{2}));
183+
}
184+
185+
BOOST_AUTO_TEST_CASE(call_multiple_arguments_mixed_format)
186+
{
187+
char const* source = R"(
188+
// f(uint256, uint256): -1, 2
189+
// -> 1, -2
190+
)";
191+
auto const& calls = parse(source);
192+
BOOST_CHECK_EQUAL(calls.size(), 1);
193+
194+
auto const& call = calls.at(0);
195+
BOOST_CHECK_EQUAL(call.signature, "f(uint256, uint256)");
196+
BOOST_CHECK_EQUAL(call.arguments.raw, "-1, 2");
197+
ABI_CHECK(call.arguments.rawBytes, toBigEndian(u256{-1}) + toBigEndian(u256{2}));
198+
ABI_CHECK(call.expectations.rawBytes, toBigEndian(u256{1}) + toBigEndian(u256{-2}));
199+
}
200+
201+
BOOST_AUTO_TEST_CASE(parser_convert_string_to_bytes)
202+
{
203+
string raw{"1, -1"};
204+
auto bytesFormat = TestFileParser::formattedStringToBytes(raw);
205+
ABI_CHECK(bytesFormat.first, toBigEndian(u256{1}) + toBigEndian(u256{-1}));
206+
BOOST_CHECK_EQUAL(bytesFormat.second.size(), 2);
207+
BOOST_CHECK_EQUAL(bytesFormat.second.at(0).type, ByteFormat::UnsignedDec);
208+
BOOST_CHECK_EQUAL(bytesFormat.second.at(1).type, ByteFormat::SignedDec);
209+
}
210+
211+
BOOST_AUTO_TEST_CASE(parser_convert_bytes_to_string)
212+
{
213+
bytes rawBytes = toBigEndian(u256{1}) + toBigEndian(u256{-1});
214+
vector<ByteFormat> formats
215+
{
216+
ByteFormat{ByteFormat::UnsignedDec},
217+
ByteFormat{ByteFormat::SignedDec}
218+
};
219+
string formatted = TestFileParser::bytesToFormattedString(rawBytes, formats);
220+
BOOST_CHECK_EQUAL(formatted, "1,-1");
221+
}
222+
223+
224+
BOOST_AUTO_TEST_SUITE_END()
225+
226+
}
227+
}
228+
}

0 commit comments

Comments
 (0)