Right-aligns hex numbers and introduces alignment built-ins.

This commit is contained in:
Erik Kundt 2019-02-28 14:16:16 +01:00
parent eb5bde95b3
commit a40fbf0fc4
8 changed files with 359 additions and 112 deletions

View File

@ -75,12 +75,12 @@ bool SemanticTest::run(ostream& _stream, string const& _linePrefix, bool const _
AnsiColorized(_stream, _formatted, {BOLD, CYAN}) << _linePrefix << "Expected result:" << endl;
for (auto const& test: m_tests)
_stream << test.format(_linePrefix, false, _formatted) << endl;
_stream << endl;
AnsiColorized(_stream, _formatted, {BOLD, CYAN}) << _linePrefix << "Obtained result:" << endl;
for (auto const& test: m_tests)
_stream << test.format(_linePrefix, true, _formatted) << endl;
AnsiColorized(_stream, _formatted, {BOLD, RED}) << _linePrefix
AnsiColorized(_stream, _formatted, {BOLD, RED}) << _linePrefix << endl << _linePrefix
<< "Attention: Updates on the test will apply the detected format displayed." << endl;
return false;
}

View File

@ -1,6 +1,6 @@
contract C {
function f() public returns (uint) {
return 1;
return 2;
}
function g(uint x, uint y) public returns (uint) {
return x - y;
@ -8,18 +8,20 @@ contract C {
function h() public payable returns (uint) {
return f();
}
function x(bytes32 b) public returns (bytes32) {
function i(bytes32 b) public returns (bytes32) {
return b;
}
function t(bool b) public returns (bool) {
function j(bool b) public returns (bool) {
return !b;
}
function k(bytes32 b) public returns (bytes32) {
return b;
}
}
// ----
// f() -> 1
// f() -> 2
// g(uint256,uint256): 1, -2 -> 3
// h(), 1 ether -> 1
// j() -> FAILURE
// i() # Does not exist. # -> FAILURE # Reverts. #
// x(bytes32): 0x31 -> 0x31
// t(bool): true -> false
// h(), 1 ether -> 2
// i() -> FAILURE
// j(bool): true -> false
// k(bytes32): 0x31 -> 0x31

View File

@ -0,0 +1,28 @@
contract C {
uint256 public stateDecimal = 0x20;
}
contract D {
bool public stateBool = true;
uint256 public stateDecimal = 42;
bytes32 public stateBytes = "\x42\x00\xef";
function internalStateDecimal() public returns (uint256) {
return (new C()).stateDecimal();
}
function update(bool _bool, uint256 _decimal, bytes32 _bytes) public returns (bool, uint256, bytes32) {
stateBool = _bool;
stateDecimal = _decimal;
stateBytes = _bytes;
return (stateBool, stateDecimal, stateBytes);
}
}
// ----
// stateBool() -> true
// stateBool() -> right(true)
// stateDecimal() -> 42
// stateDecimal() -> right(42)
// stateBytes() -> left(0x4200ef)
// internalStateDecimal() -> 0x20
// update(bool,uint256,bytes32): false, -23, left(0x2300ef) -> false, -23, left(0x2300ef)

View File

@ -33,6 +33,45 @@ using namespace dev::solidity::test;
using namespace std;
using namespace soltest;
namespace
{
enum class DeclaredAlignment
{
Left,
Right,
None,
};
inline bytes alignLeft(bytes _bytes)
{
return std::move(_bytes) + bytes(32 - _bytes.size(), 0);
}
inline bytes alignRight(bytes _bytes)
{
return bytes(32 - _bytes.size(), 0) + std::move(_bytes);
}
inline bytes applyAlign(DeclaredAlignment _alignment, ABIType& _abiType, bytes _converted)
{
if (_alignment != DeclaredAlignment::None)
_abiType.alignDeclared = true;
switch (_alignment)
{
case DeclaredAlignment::Left:
_abiType.align = ABIType::AlignLeft;
return alignLeft(std::move(_converted));
case DeclaredAlignment::Right:
_abiType.align = ABIType::AlignRight;
return alignRight(std::move(_converted));
default:
_abiType.align = ABIType::AlignRight;
return alignRight(std::move(_converted));
}
}
}
vector<dev::solidity::test::FunctionCall> TestFileParser::parseFunctionCalls()
{
vector<FunctionCall> calls;
@ -137,9 +176,16 @@ string TestFileParser::parseFunctionSignature()
u256 TestFileParser::parseFunctionCallValue()
{
u256 value = convertNumber(parseDecimalNumber());
expect(Token::Ether);
return value;
try
{
u256 value{parseDecimalNumber()};
expect(Token::Ether);
return value;
}
catch (std::exception const&)
{
throw Error(Error::Type::ParserError, "Ether value encoding invalid.");
}
}
FunctionCallArgs TestFileParser::parseFunctionCallArguments()
@ -192,51 +238,75 @@ Parameter TestFileParser::parseParameter()
tuple<bytes, ABIType, string> TestFileParser::parseABITypeLiteral()
{
ABIType abiType{ABIType::None, ABIType::AlignNone, 0};
DeclaredAlignment alignment{DeclaredAlignment::None};
bytes result{toBigEndian(u256{0})};
string rawString;
bool isSigned = false;
if (accept(Token::Left, true))
{
rawString += formatToken(Token::Left);
expect(Token::LParen);
rawString += formatToken(Token::LParen);
alignment = DeclaredAlignment::Left;
}
if (accept(Token::Right, true))
{
rawString += formatToken(Token::Right);
expect(Token::LParen);
rawString += formatToken(Token::LParen);
alignment = DeclaredAlignment::Right;
}
try
{
u256 number{0};
ABIType abiType{ABIType::None, ABIType::AlignRight, 0};
string rawString;
if (accept(Token::Sub))
if (accept(Token::Sub, true))
{
abiType = ABIType{ABIType::SignedDec, ABIType::AlignRight, 32};
expect(Token::Sub);
rawString += formatToken(Token::Sub);
isSigned = true;
}
if (accept(Token::Boolean))
{
if (isSigned)
throw Error(Error::Type::ParserError, "Invalid boolean literal.");
abiType = ABIType{ABIType::Boolean, ABIType::AlignRight, 32};
string parsed = parseBoolean();
rawString += parsed;
result = applyAlign(alignment, abiType, convertBoolean(parsed));
}
else if (accept(Token::HexNumber))
{
if (isSigned)
throw Error(Error::Type::ParserError, "Invalid hex number literal.");
abiType = ABIType{ABIType::Hex, ABIType::AlignRight, 32};
string parsed = parseHexNumber();
rawString += parsed;
result = applyAlign(alignment, abiType, convertHexNumber(parsed));
}
else if (accept(Token::Number))
{
auto type = isSigned ? ABIType::SignedDec : ABIType::UnsignedDec;
abiType = ABIType{type, ABIType::AlignRight, 32};
string parsed = parseDecimalNumber();
rawString += parsed;
number = convertNumber(parsed) * -1;
if (isSigned)
parsed = "-" + parsed;
result = applyAlign(alignment, abiType, convertNumber(parsed));
}
else
else if (accept(Token::Failure, true))
{
if (accept(Token::Boolean))
{
abiType = ABIType{ABIType::Boolean, ABIType::AlignRight, 32};
string parsed = parseBoolean();
rawString += parsed;
return make_tuple(toBigEndian(u256{convertBoolean(parsed)}), abiType, rawString);
}
else if (accept(Token::HexNumber))
{
abiType = ABIType{ABIType::Hex, ABIType::AlignLeft, 32};
string parsed = parseHexNumber();
rawString += parsed;
return make_tuple(convertHexNumber(parsed), abiType, rawString);
}
else if (accept(Token::Number))
{
abiType = ABIType{ABIType::UnsignedDec, ABIType::AlignRight, 32};
string parsed = parseDecimalNumber();
rawString += parsed;
number = convertNumber(parsed);
}
else if (accept(Token::Failure, true))
{
abiType = ABIType{ABIType::Failure, ABIType::AlignRight, 0};
return make_tuple(bytes{}, abiType, rawString);
}
if (isSigned)
throw Error(Error::Type::ParserError, "Invalid failure literal.");
abiType = ABIType{ABIType::Failure, ABIType::AlignRight, 0};
result = bytes{};
}
return make_tuple(toBigEndian(number), abiType, rawString);
if (alignment != DeclaredAlignment::None)
{
expect(Token::RParen);
rawString += formatToken(Token::RParen);
}
return make_tuple(result, abiType, rawString);
}
catch (std::exception const&)
{
@ -298,21 +368,21 @@ string TestFileParser::parseHexNumber()
return literal;
}
bool TestFileParser::convertBoolean(string const& _literal)
bytes TestFileParser::convertBoolean(string const& _literal)
{
if (_literal == "true")
return true;
return bytes{true};
else if (_literal == "false")
return false;
return bytes{false};
else
throw Error(Error::Type::ParserError, "Boolean literal invalid.");
}
u256 TestFileParser::convertNumber(string const& _literal)
bytes TestFileParser::convertNumber(string const& _literal)
{
try
{
return u256{_literal};
return toCompactBigEndian(u256{_literal});
}
catch (std::exception const&)
{
@ -330,8 +400,7 @@ bytes TestFileParser::convertHexNumber(string const& _literal)
}
else
{
bytes result = fromHex(_literal);
return result + bytes(32 - result.size(), 0);
return fromHex(_literal);
}
}
catch (std::exception const&)
@ -357,6 +426,8 @@ void TestFileParser::Scanner::scanNextToken()
if (_literal == "true") return TokenDesc{Token::Boolean, _literal};
if (_literal == "false") return TokenDesc{Token::Boolean, _literal};
if (_literal == "ether") return TokenDesc{Token::Ether, _literal};
if (_literal == "left") return TokenDesc{Token::Left, _literal};
if (_literal == "right") return TokenDesc{Token::Right, _literal};
if (_literal == "FAILURE") return TokenDesc{Token::Failure, _literal};
return TokenDesc{Token::Identifier, _literal};
};

View File

@ -62,6 +62,8 @@ namespace test
K(Ether, "ether", 0) \
K(Boolean, "boolean", 0) \
/* special keywords */ \
K(Left, "left", 0) \
K(Right, "right", 0) \
K(Failure, "FAILURE", 0) \
namespace soltest
@ -112,12 +114,13 @@ struct ABIType
enum Align
{
AlignLeft,
AlignRight
AlignRight,
AlignNone,
};
Type type = ABIType::None;
Align align = ABIType::AlignRight;
size_t size = 0;
bool alignDeclared = false;
};
/**
@ -370,16 +373,15 @@ private:
/// Parses the current hex number literal.
std::string parseHexNumber();
/// Coverts "true" to `true`, "false" to `false` and throws
/// otherwise.
bool convertBoolean(std::string const& _literal);
/// Tries to convert \param _literal to an unpadded `bytes`
/// representation of the boolean number literal. Throws if conversion fails.
bytes convertBoolean(std::string const& _literal);
/// Tries to convert \param _literal to right-aligned, padded `u256`
/// representation of the decimal number literal.
/// Throws if conversion fails.
u256 convertNumber(std::string const& _literal);
/// Tries to convert \param _literal to an unpadded `bytes`
/// representation of the decimal number literal. Throws if conversion fails.
bytes convertNumber(std::string const& _literal);
/// Tries to convert \param _literal to left-aligned, padded `bytes`
/// Tries to convert \param _literal to an unpadded `bytes`
/// representation of the hex literal. Throws if conversion fails.
bytes convertHexNumber(std::string const& _literal);

View File

@ -336,8 +336,8 @@ BOOST_AUTO_TEST_CASE(call_arguments_left_aligned)
"f(bytes32,bytes32)",
false,
fmt::encodeArgs(
u256("0x6161000000000000000000000000000000000000000000000000000000000000"),
u256("0x420000EF00000000000000000000000000000000000000000000000000000000")
fromHex("0x6161"),
fromHex("0x420000EF")
),
fmt::encodeArgs(1)
);
@ -347,8 +347,8 @@ BOOST_AUTO_TEST_CASE(call_arguments_left_aligned)
"g(bytes32,bytes32)",
false,
fmt::encodeArgs(
u256("0x0616000000000000000000000000000000000000000000000000000000000000"),
u256("0x0042EF0000000000000000000000000000000000000000000000000000000000")
fromHex("0x0616"),
fromHex("0x0042EF00")
),
fmt::encodeArgs(1)
);
@ -493,6 +493,46 @@ BOOST_AUTO_TEST_CASE(call_raw_arguments)
);
}
BOOST_AUTO_TEST_CASE(call_builtin_left_decimal)
{
char const* source = R"(
// f(): left(1), left(0x20) -> left(-2), left(true)
)";
auto const calls = parse(source);
BOOST_REQUIRE_EQUAL(calls.size(), 1);
testFunctionCall(
calls.at(0),
Mode::SingleLine,
"f()",
false,
fmt::encodeArgs(
fmt::encode(toCompactBigEndian(u256{1}), false),
fmt::encode(fromHex("0x20"), false)
),
fmt::encodeArgs(
fmt::encode(toCompactBigEndian(u256{-2}), false),
fmt::encode(bytes{true}, false)
)
);
}
BOOST_AUTO_TEST_CASE(call_builtin_right_decimal)
{
char const* source = R"(
// f(): right(1), right(0x20) -> right(-2), right(true)
)";
auto const calls = parse(source);
BOOST_REQUIRE_EQUAL(calls.size(), 1);
testFunctionCall(
calls.at(0),
Mode::SingleLine,
"f()",
false,
fmt::encodeArgs(1, fromHex("0x20")),
fmt::encodeArgs(-2, true)
);
}
BOOST_AUTO_TEST_CASE(call_newline_invalid)
{
char const* source = R"(
@ -603,6 +643,30 @@ BOOST_AUTO_TEST_CASE(call_hex_number_invalid)
BOOST_REQUIRE_THROW(parse(source), langutil::Error);
}
BOOST_AUTO_TEST_CASE(call_signed_bool_invalid)
{
char const* source = R"(
// f() -> -true
)";
BOOST_REQUIRE_THROW(parse(source), langutil::Error);
}
BOOST_AUTO_TEST_CASE(call_signed_failure_invalid)
{
char const* source = R"(
// f() -> -FAILURE
)";
BOOST_REQUIRE_THROW(parse(source), langutil::Error);
}
BOOST_AUTO_TEST_CASE(call_signed_hex_number_invalid)
{
char const* source = R"(
// f() -> -0x42
)";
BOOST_REQUIRE_THROW(parse(source), langutil::Error);
}
BOOST_AUTO_TEST_CASE(call_arguments_colon)
{
char const* source = R"(

View File

@ -48,7 +48,11 @@ string TestFunctionCall::format(string const& _linePrefix, bool const _renderRes
if (!m_call.arguments.rawBytes().empty())
{
string output = formatRawParameters(m_call.arguments.parameters, _linePrefix);
_stream << colon << output;
_stream << colon;
if (_singleLine)
_stream << ws;
_stream << output;
}
/// Formats comments on the function parameters and the arrow taking
@ -76,13 +80,19 @@ string TestFunctionCall::format(string const& _linePrefix, bool const _renderRes
{
bytes output = m_call.expectations.rawBytes();
bool const isFailure = m_call.expectations.failure;
result = isFailure ? failure : formatBytesParameters(output, m_call.expectations.result);
result = isFailure ?
failure :
formatRawParameters(m_call.expectations.result);
}
else
{
bytes output = m_rawBytes;
bool const isFailure = m_failure;
result = isFailure ? failure : formatBytesParameters(output, m_call.expectations.result);
result = isFailure ?
failure :
matchesExpectation() ?
formatRawParameters(m_call.expectations.result) :
formatBytesParameters(output, m_call.expectations.result);
}
AnsiColorized(_stream, highlight, {dev::formatting::RED_BACKGROUND}) << result;
@ -106,8 +116,6 @@ string TestFunctionCall::format(string const& _linePrefix, bool const _renderRes
formatOutput(true);
else
formatOutput(false);
// _stream << endl;
return _stream.str();
}
@ -131,14 +139,12 @@ string TestFunctionCall::formatBytesParameters(bytes const& _bytes, dev::solidit
// be signed. If an unsigned was detected in the expectations,
// but the actual result returned a signed, it would be formatted
// incorrectly.
soltestAssert(param.abiType.align == ABIType::AlignRight, "Unsigned decimals must be right-aligned.");
if (*byteRange.begin() & 0x80)
resultStream << u2s(fromBigEndian<u256>(byteRange));
else
resultStream << fromBigEndian<u256>(byteRange);
break;
case ABIType::SignedDec:
soltestAssert(param.abiType.align == ABIType::AlignRight, "Signed decimals must be right-aligned.");
if (*byteRange.begin() & 0x80)
resultStream << u2s(fromBigEndian<u256>(byteRange));
else
@ -146,19 +152,16 @@ string TestFunctionCall::formatBytesParameters(bytes const& _bytes, dev::solidit
break;
case ABIType::Boolean:
{
soltestAssert(param.abiType.align == ABIType::AlignRight, "Booleans must be right-aligned.");
u256 result = fromBigEndian<u256>(byteRange);
if (result == 0)
resultStream << "false";
else
else if (result == 1)
resultStream << "true";
else
resultStream << result;
break;
}
case ABIType::Hex:
soltestAssert(param.abiType.align == ABIType::AlignLeft, "Hex numbers must be left-aligned.");
byteRange.erase(
std::remove(byteRange.begin(), byteRange.end(), 0), byteRange.end()
);
resultStream << toHex(byteRange, HexPrefix::Add);
break;
case ABIType::Failure:
@ -180,10 +183,10 @@ string TestFunctionCall::formatRawParameters(dev::solidity::test::ParameterList
for (auto const& param: _params)
{
if (param.format.newline)
resultStream << endl << _linePrefix << "//";
resultStream << " " << param.rawString;
resultStream << endl << _linePrefix << "// ";
resultStream << param.rawString;
if (&param != &_params.back())
resultStream << ",";
resultStream << ", ";
}
return resultStream.str();
}

View File

@ -47,6 +47,43 @@ BOOST_AUTO_TEST_CASE(format_unsigned_singleline)
TestFunctionCall test{call};
BOOST_REQUIRE_EQUAL(test.format(), "// f(uint8): 1 -> 1");
test.setRawBytes(toBigEndian(u256{2}));
test.setFailure(false);
BOOST_REQUIRE_EQUAL(test.format("", true), "// f(uint8): 1 -> 2");
}
BOOST_AUTO_TEST_CASE(format_unsigned_singleline_signed_encoding)
{
bytes expectedBytes = toBigEndian(u256{1});
ABIType abiType{ABIType::UnsignedDec, ABIType::AlignRight, 32};
Parameter param{expectedBytes, "1", abiType, FormatInfo{}};
FunctionCallExpectations expectations{vector<Parameter>{param}, false, string{}};
FunctionCallArgs arguments{vector<Parameter>{param}, string{}};
FunctionCall call{"f(uint8)", 0, arguments, expectations};
TestFunctionCall test{call};
BOOST_REQUIRE_EQUAL(test.format(), "// f(uint8): 1 -> 1");
test.setRawBytes(toBigEndian(u256{-1}));
test.setFailure(false);
BOOST_REQUIRE_EQUAL(test.format("", true), "// f(uint8): 1 -> -1");
}
BOOST_AUTO_TEST_CASE(format_unsigned_multiline)
{
bytes expectedBytes = toBigEndian(u256{1});
ABIType abiType{ABIType::UnsignedDec, ABIType::AlignRight, 32};
Parameter result{expectedBytes, "1", abiType, FormatInfo{}};
FunctionCallExpectations expectations{vector<Parameter>{result}, false, string{}};
FunctionCallArgs arguments{vector<Parameter>{}, string{}};
FunctionCall call{"f(uint8)", 0, arguments, expectations};
call.displayMode = FunctionCall::DisplayMode::MultiLine;
TestFunctionCall test{call};
BOOST_REQUIRE_EQUAL(test.format(), "// f(uint8)\n// -> 1");
}
BOOST_AUTO_TEST_CASE(format_multiple_unsigned_singleline)
@ -73,23 +110,14 @@ BOOST_AUTO_TEST_CASE(format_signed_singleline)
TestFunctionCall test{call};
BOOST_REQUIRE_EQUAL(test.format(), "// f(int8): -1 -> -1");
test.setRawBytes(toBigEndian(u256{-2}));
test.setFailure(false);
BOOST_REQUIRE_EQUAL(test.format("", true), "// f(int8): -1 -> -2");
}
BOOST_AUTO_TEST_CASE(format_hex_singleline)
{
bytes result = fromHex("0x31");
bytes expectedBytes = result + bytes(32 - result.size(), 0);
ABIType abiType{ABIType::Hex, ABIType::AlignLeft, 32};
Parameter param{expectedBytes, "0x31", abiType, FormatInfo{}};
FunctionCallExpectations expectations{vector<Parameter>{param}, false, string{}};
FunctionCallArgs arguments{vector<Parameter>{param}, string{}};
FunctionCall call{"f(bytes32)", 0, arguments, expectations};
TestFunctionCall test{call};
BOOST_REQUIRE_EQUAL(test.format(), "// f(bytes32): 0x31 -> 0x31");
}
BOOST_AUTO_TEST_CASE(format_hex_right_align)
{
bytes result = fromHex("0x31");
bytes expectedBytes = result + bytes(32 - result.size(), 0);
@ -100,7 +128,14 @@ BOOST_AUTO_TEST_CASE(format_hex_right_align)
FunctionCall call{"f(bytes32)", 0, arguments, expectations};
TestFunctionCall test{call};
BOOST_REQUIRE_THROW(test.format(), runtime_error);
BOOST_REQUIRE_EQUAL(test.format(), "// f(bytes32): 0x31 -> 0x31");
bytes actualResult = fromHex("0x32");
bytes actualBytes = actualResult + bytes(32 - actualResult.size(), 0);
test.setRawBytes(actualBytes);
test.setFailure(false);
BOOST_REQUIRE_EQUAL(test.format("", true), "// f(bytes32): 0x31 -> 0x3200000000000000000000000000000000000000000000000000000000000000");
}
BOOST_AUTO_TEST_CASE(format_bool_true_singleline)
@ -114,6 +149,13 @@ BOOST_AUTO_TEST_CASE(format_bool_true_singleline)
TestFunctionCall test{call};
BOOST_REQUIRE_EQUAL(test.format(), "// f(bool): true -> true");
bytes actualResult = bytes{false};
bytes actualBytes = actualResult + bytes(32 - actualResult.size(), 0);
test.setRawBytes(actualBytes);
test.setFailure(false);
BOOST_REQUIRE_EQUAL(test.format("", true), "// f(bool): true -> false");
}
BOOST_AUTO_TEST_CASE(format_bool_false_singleline)
@ -129,48 +171,79 @@ BOOST_AUTO_TEST_CASE(format_bool_false_singleline)
BOOST_REQUIRE_EQUAL(test.format(), "// f(bool): false -> false");
}
BOOST_AUTO_TEST_CASE(format_bool_left_align_singleline)
BOOST_AUTO_TEST_CASE(format_bool_left_singleline)
{
bytes expectedBytes = toBigEndian(u256{true});
bytes expectedBytes = toBigEndian(u256{false});
ABIType abiType{ABIType::Boolean, ABIType::AlignLeft, 32};
Parameter param{expectedBytes, "true", abiType, FormatInfo{}};
Parameter param{expectedBytes, "left(false)", abiType, FormatInfo{}};
FunctionCallExpectations expectations{vector<Parameter>{param}, false, string{}};
FunctionCallArgs arguments{vector<Parameter>{param}, string{}};
FunctionCall call{"f(bool)", 0, arguments, expectations};
TestFunctionCall test{call};
BOOST_REQUIRE_THROW(test.format(), runtime_error);
BOOST_REQUIRE_EQUAL(test.format(), "// f(bool): left(false) -> left(false)");
}
BOOST_AUTO_TEST_CASE(format_hex_number_right_singleline)
{
bytes result = fromHex("0x42");
bytes expectedBytes = result + bytes(32 - result.size(), 0);
ABIType abiType{ABIType::Hex, ABIType::AlignRight, 32};
Parameter param{expectedBytes, "right(0x42)", abiType, FormatInfo{}};
FunctionCallExpectations expectations{vector<Parameter>{param}, false, string{}};
FunctionCallArgs arguments{vector<Parameter>{param}, string{}};
FunctionCall call{"f(bool)", 0, arguments, expectations};
TestFunctionCall test{call};
BOOST_REQUIRE_EQUAL(test.format(), "// f(bool): right(0x42) -> right(0x42)");
}
BOOST_AUTO_TEST_CASE(format_empty_byte_range)
{
bytes expectedBytes;
ABIType abiType{ABIType::UnsignedDec, ABIType::AlignRight, 32};
ABIType abiType{ABIType::None, ABIType::AlignNone, 0};
Parameter param{expectedBytes, "1", abiType, FormatInfo{}};
FunctionCallExpectations expectations{vector<Parameter>{param}, false, string{}};
FunctionCallArgs arguments{vector<Parameter>{}, string{}};
FunctionCall call{"f()", 0, arguments, expectations};
TestFunctionCall test{call};
BOOST_REQUIRE_EQUAL(test.format(), "// f() -> ");
BOOST_REQUIRE_EQUAL(test.format(), "// f() -> 1");
}
BOOST_AUTO_TEST_CASE(format_failure_singleline)
{
bytes expectedBytes = toBigEndian(u256{1});
ABIType abiType{ABIType::UnsignedDec, ABIType::AlignRight, 32};
Parameter param{expectedBytes, "1", abiType, FormatInfo{}};
FunctionCallExpectations expectations{vector<Parameter>{}, true, string{}};
FunctionCallArgs arguments{vector<Parameter>{param}, string{}};
FunctionCall call{"f(uint8)", 0, arguments, expectations};
TestFunctionCall test{call};
BOOST_REQUIRE_EQUAL(test.format(), "// f(uint8): 1 -> FAILURE");
}
BOOST_AUTO_TEST_CASE(format_parameter_encoding_too_short)
{
bytes expectedBytes = toBigEndian(u256{1}) + toBigEndian(u256{1});
ABIType abiType{ABIType::UnsignedDec, ABIType::AlignRight, 32};
ABIType abiType{ABIType::UnsignedDec, ABIType::AlignRight, 20};
Parameter param{expectedBytes, "1", abiType, FormatInfo{}};
FunctionCallExpectations expectations{vector<Parameter>{param, param}, false, string{}};
FunctionCallArgs arguments{vector<Parameter>{param, param}, string{}};
FunctionCall call{"f(uint8, uint8)", 0, arguments, expectations};
TestFunctionCall test{call};
BOOST_REQUIRE_THROW(test.format(), runtime_error);
bytes resultBytes = toBigEndian(u256{1}) + toBigEndian(u256{2});
test.setRawBytes(resultBytes);
test.setFailure(false);
BOOST_REQUIRE_THROW(test.format("", true), runtime_error);
}
BOOST_AUTO_TEST_CASE(format_byte_range_too_short)
{
bytes expectedBytes{0};
bytes expectedBytes = toBigEndian(u256{1});
ABIType abiType{ABIType::UnsignedDec, ABIType::AlignRight, 32};
Parameter param{expectedBytes, "1", abiType, FormatInfo{}};
FunctionCallExpectations expectations{vector<Parameter>{param, param}, false, string{}};
@ -178,7 +251,11 @@ BOOST_AUTO_TEST_CASE(format_byte_range_too_short)
FunctionCall call{"f(uint8, uint8)", 0, arguments, expectations};
TestFunctionCall test{call};
BOOST_REQUIRE_THROW(test.format(), runtime_error);
bytes resultBytes{0};
test.setRawBytes(resultBytes);
test.setFailure(false);
BOOST_REQUIRE_THROW(test.format("", true), runtime_error);
}
BOOST_AUTO_TEST_SUITE_END()