28
28
using namespace dev ;
29
29
using namespace solidity ;
30
30
using namespace dev ::solidity::test;
31
- using namespace dev ::solidity::test:: formatting;
31
+ using namespace dev ::formatting;
32
32
using namespace std ;
33
- namespace fs = boost::filesystem;
34
33
using namespace boost ;
35
34
using namespace boost ::algorithm;
36
35
using namespace boost ::unit_test;
36
+ namespace fs = boost::filesystem;
37
37
38
38
namespace
39
39
{
40
- using ParamList = dev::solidity::test::ParameterList;
41
- using FunctionCallTest = dev::solidity::test::SemanticTest::FunctionCallTest;
40
+ using FunctionCallTest = SemanticTest::FunctionCallTest;
42
41
using FunctionCall = dev::solidity::test::FunctionCall;
42
+ using ParamList = dev::solidity::test::ParameterList;
43
+
43
44
44
- string formatBytes (bytes const & _bytes, ParamList const & _params, bool const _formatInvalid = false )
45
+ string formatBytes (bytes const & _bytes, ParamList const & _params)
45
46
{
46
47
stringstream resultStream;
47
48
if (_bytes.empty ())
48
- resultStream. str () ;
49
+ return {} ;
49
50
auto it = _bytes.begin ();
50
51
for (auto const & param: _params)
51
52
{
52
- bytes byteRange{it, it + param.abiType .size };
53
- // FIXME Check range
54
- // TODO Check range
53
+ long offset = static_cast <long >(param.abiType .size );
54
+ auto offsetIter = it + offset;
55
+ soltestAssert (offsetIter <= _bytes.end (), " Byte range can not be extended past the end of given bytes." );
56
+
57
+ bytes byteRange{it, offsetIter};
55
58
switch (param.abiType .type )
56
59
{
57
60
case ABIType::SignedDec:
@@ -71,64 +74,116 @@ namespace
71
74
resultStream << fromBigEndian<u256>(byteRange);
72
75
break ;
73
76
case ABIType::Failure:
74
- // If expectations are empty, the encoding type is invalid.
75
- // In order to still print the actual result even if
76
- // empty expectations were detected, it must be forced.
77
- if (_formatInvalid)
78
- resultStream << fromBigEndian<u256>(byteRange);
79
77
break ;
80
78
case ABIType::None:
81
- // If expectations are empty, the encoding type is NONE.
82
- if (_formatInvalid)
83
- resultStream << fromBigEndian<u256>(byteRange);
84
79
break ;
85
80
}
86
- it += param. abiType . size ;
81
+ it += offset ;
87
82
if (it != _bytes.end () && !(param.abiType .type == ABIType::None))
88
83
resultStream << " , " ;
89
84
}
85
+ soltestAssert (it == _bytes.end (), " Parameter encoding too short for the given byte range." );
86
+ return resultStream.str ();
87
+ }
88
+
89
+ string formatRawArguments (ParamList const & _params, string const & _linePrefix = " " )
90
+ {
91
+ stringstream resultStream;
92
+ for (auto const & param: _params)
93
+ {
94
+ if (param.format .newline )
95
+ resultStream << endl << _linePrefix << " //" ;
96
+ resultStream << " " << param.rawString ;
97
+ if (¶m != &_params.back ())
98
+ resultStream << " ," ;
99
+ }
90
100
return resultStream.str ();
91
101
}
92
102
93
103
string formatFunctionCallTest (
94
104
FunctionCallTest const & _test,
95
105
string const & _linePrefix = " " ,
96
106
bool const _renderResult = false ,
97
- bool const _higlight = false
107
+ bool const _highlight = false
98
108
)
99
109
{
110
+ using namespace soltest ;
111
+ using Token = soltest::Token;
112
+
100
113
stringstream _stream;
101
114
FunctionCall call = _test.call ;
102
- bool hightlight = !_test.matchesExpectation () && _higlight ;
115
+ bool highlight = !_test.matchesExpectation () && _highlight ;
103
116
104
117
auto formatOutput = [&](bool const _singleLine)
105
118
{
106
- _stream << _linePrefix << " // " << call.signature ;
119
+ string ws = " " ;
120
+ string arrow = formatToken (Token::Arrow);
121
+ string colon = formatToken (Token::Colon);
122
+ string comma = formatToken (Token::Comma);
123
+ string comment = formatToken (Token::Comment);
124
+ string ether = formatToken (Token::Ether);
125
+ string newline = formatToken (Token::Newline);
126
+ string failure = formatToken (Token::Failure);
127
+
128
+ // / Prints the function signature. This is the same independent from the display-mode.
129
+ _stream << _linePrefix << newline << ws << call.signature ;
107
130
if (call.value > u256 (0 ))
108
- _stream << TestFileParser::formatToken (SoltToken::Comma)
109
- << call.value << " "
110
- << TestFileParser::formatToken (SoltToken::Ether);
131
+ _stream << comma << ws << call.value << ws << ether;
111
132
if (!call.arguments .rawBytes ().empty ())
112
- _stream << " : "
113
- << formatBytes (call.arguments .rawBytes (), call.arguments .parameters );
114
- if (!_singleLine)
115
- _stream << endl << _linePrefix << " // " ;
133
+ {
134
+ string output = formatRawArguments (call.arguments .parameters , _linePrefix);
135
+ _stream << colon << output;
136
+ }
137
+
138
+ // / Prints comments on the function parameters and the arrow taking
139
+ // / the display-mode into account.
116
140
if (_singleLine)
117
- _stream << " " ;
118
- _stream << " -> " ;
119
- if (!_singleLine)
120
- _stream << endl << _linePrefix << " // " ;
121
- if (hightlight)
122
- _stream << formatting::RED_BACKGROUND;
123
- bytes output;
124
- if (_renderResult)
125
- output = call.expectations .rawBytes ();
141
+ {
142
+ if (!call.arguments .comment .empty ())
143
+ _stream << ws << comment << call.arguments .comment << comment;
144
+ _stream << ws << arrow << ws;
145
+ }
146
+ else
147
+ {
148
+ _stream << endl << _linePrefix << newline << ws;
149
+ if (!call.arguments .comment .empty ())
150
+ {
151
+ _stream << comment << call.arguments .comment << comment;
152
+ _stream << endl << _linePrefix << newline << ws;
153
+ }
154
+ _stream << arrow << ws;
155
+ }
156
+
157
+ // / Print either the expected output or the actual result output
158
+ string result;
159
+ if (!_renderResult)
160
+ {
161
+ bytes output = call.expectations .rawBytes ();
162
+ bool const isFailure = call.expectations .failure ;
163
+ result = isFailure ? failure : formatBytes (output, call.expectations .result );
164
+ }
126
165
else
127
- output = _test.rawBytes ;
128
- if (!output.empty ())
129
- _stream << formatBytes (output, call.expectations .result );
130
- if (hightlight)
131
- _stream << formatting::RESET;
166
+ {
167
+ bytes output = _test.rawBytes ;
168
+ bool const isFailure = _test.failure ;
169
+ result = isFailure ? failure : formatBytes (output, call.expectations .result );
170
+ }
171
+ AnsiColorized (_stream, highlight, {RED_BACKGROUND}) << result;
172
+
173
+ // / Print comments on expectations taking the display-mode into account.
174
+ if (_singleLine)
175
+ {
176
+ if (!call.expectations .comment .empty ())
177
+ _stream << ws << comment << call.expectations .comment << comment;
178
+ }
179
+ else
180
+ {
181
+ if (!call.expectations .comment .empty ())
182
+ {
183
+ _stream << endl << _linePrefix << newline << ws;
184
+ _stream << comment << call.expectations .comment << comment;
185
+ }
186
+ }
132
187
};
133
188
134
189
if (call.displayMode == FunctionCall::DisplayMode::SingleLine)
@@ -145,8 +200,7 @@ SemanticTest::SemanticTest(string const& _filename, string const& _ipcPath):
145
200
SolidityExecutionFramework(_ipcPath)
146
201
{
147
202
ifstream file (_filename);
148
- if (!file)
149
- BOOST_THROW_EXCEPTION (runtime_error (" Cannot open test contract: \" " + _filename + " \" ." ));
203
+ soltestAssert (file, " Cannot open test contract: \" " + _filename + " \" ." );
150
204
file.exceptions (ios::badbit);
151
205
152
206
m_source = parseSource (file);
@@ -155,8 +209,7 @@ SemanticTest::SemanticTest(string const& _filename, string const& _ipcPath):
155
209
156
210
bool SemanticTest::run (ostream& _stream, string const & _linePrefix, bool const _formatted)
157
211
{
158
- if (!deploy (" " , 0 , bytes ()))
159
- BOOST_THROW_EXCEPTION (runtime_error (" Failed to deploy contract." ));
212
+ soltestAssert (deploy (" " , 0 , bytes ()), " Failed to deploy contract." );
160
213
161
214
bool success = true ;
162
215
for (auto & test: m_tests)
@@ -179,15 +232,15 @@ bool SemanticTest::run(ostream& _stream, string const& _linePrefix, bool const _
179
232
180
233
if (!success)
181
234
{
182
- FormattedScope (_stream, _formatted, {BOLD, CYAN}) << _linePrefix << " Expected result:" << endl;
235
+ AnsiColorized (_stream, _formatted, {BOLD, CYAN}) << _linePrefix << " Expected result:" << endl;
183
236
for (auto const & test: m_tests)
184
- _stream << formatFunctionCallTest (test, _linePrefix, false , true );
237
+ _stream << formatFunctionCallTest (test, _linePrefix, false , true & _formatted );
185
238
186
- FormattedScope (_stream, _formatted, {BOLD, CYAN}) << _linePrefix << " Obtained result:" << endl;
239
+ AnsiColorized (_stream, _formatted, {BOLD, CYAN}) << _linePrefix << " Obtained result:" << endl;
187
240
for (auto const & test: m_tests)
188
- _stream << formatFunctionCallTest (test, _linePrefix, true , true );
241
+ _stream << formatFunctionCallTest (test, _linePrefix, true , true & _formatted );
189
242
190
- FormattedScope (_stream, _formatted, {BOLD, RED}) << _linePrefix
243
+ AnsiColorized (_stream, _formatted, {BOLD, RED}) << _linePrefix
191
244
<< " Attention: Updates on the test will apply the detected format displayed." << endl;
192
245
return false ;
193
246
}
@@ -202,10 +255,10 @@ void SemanticTest::printSource(ostream& _stream, string const& _linePrefix, bool
202
255
_stream << _linePrefix << line << endl;
203
256
}
204
257
205
- void SemanticTest::printUpdatedExpectations (ostream& _stream, string const & _linePrefix ) const
258
+ void SemanticTest::printUpdatedExpectations (ostream& _stream, string const &) const
206
259
{
207
260
for (auto const & test: m_tests)
208
- _stream << formatFunctionCallTest (test, _linePrefix, false , false );
261
+ _stream << formatFunctionCallTest (test, " " , true , false );
209
262
}
210
263
211
264
void SemanticTest::parseExpectations (istream& _stream)
0 commit comments