mirror of
				https://github.com/ethereum/solidity
				synced 2023-10-03 13:03:40 +00:00 
			
		
		
		
	Cleans up test file parser and its tests.
This commit is contained in:
		
							parent
							
								
									7fa167977b
								
							
						
					
					
						commit
						161b22bd13
					
				| @ -34,21 +34,13 @@ using namespace std; | |||||||
| 
 | 
 | ||||||
| namespace | namespace | ||||||
| { | { | ||||||
| 	bool isDecimalDigit(char c) |  | ||||||
| 	{ |  | ||||||
| 		return '0' <= c && c <= '9'; |  | ||||||
| 	} |  | ||||||
| 	bool isWhiteSpace(char c) |  | ||||||
| 	{ |  | ||||||
| 		return c == ' ' || c == '\n' || c == '\t' || c == '\r'; |  | ||||||
| 	} |  | ||||||
| 	bool isIdentifierStart(char c) | 	bool isIdentifierStart(char c) | ||||||
| 	{ | 	{ | ||||||
| 		return c == '_' || c == '$' || ('a' <= c && c <= 'z') || ('A' <= c && c <= 'Z'); | 		return c == '_' || c == '$' || ('a' <= c && c <= 'z') || ('A' <= c && c <= 'Z'); | ||||||
| 	} | 	} | ||||||
| 	bool isIdentifierPart(char c) | 	bool isIdentifierPart(char c) | ||||||
| 	{ | 	{ | ||||||
| 		return isIdentifierStart(c) || isDecimalDigit(c); | 		return isIdentifierStart(c) || isdigit(c); | ||||||
| 	} | 	} | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| @ -57,33 +49,41 @@ vector<dev::solidity::test::FunctionCall> TestFileParser::parseFunctionCalls() | |||||||
| 	vector<FunctionCall> calls; | 	vector<FunctionCall> calls; | ||||||
| 	if (!accept(SoltToken::EOS)) | 	if (!accept(SoltToken::EOS)) | ||||||
| 	{ | 	{ | ||||||
| 		// TODO: check initial token state
 | 		assert(m_scanner.currentToken() == SoltToken::Unknown); | ||||||
| 		expect(SoltToken::Unknown); | 		m_scanner.scanNextToken(); | ||||||
|  | 
 | ||||||
| 		while (!accept(SoltToken::EOS)) | 		while (!accept(SoltToken::EOS)) | ||||||
| 		{ | 		{ | ||||||
| 			if (!accept(SoltToken::Whitespace)) | 			if (!accept(SoltToken::Whitespace)) | ||||||
| 			{ | 			{ | ||||||
| 				FunctionCall call; | 				FunctionCall call; | ||||||
| 
 | 
 | ||||||
|  | 				/// If this is not the first call in the test,
 | ||||||
|  | 				/// the last call to parseParameter could have eaten the
 | ||||||
|  | 				/// new line already. This could only be fixed with a one
 | ||||||
|  | 				/// token lookahead that checks parseParameter
 | ||||||
|  | 				/// if the next token is an identifier.
 | ||||||
|  | 				if (calls.empty()) | ||||||
| 					expect(SoltToken::Newline); | 					expect(SoltToken::Newline); | ||||||
| 				call.signature = parseFunctionSignature(); | 				else | ||||||
|  | 					accept(SoltToken::Newline, true); | ||||||
| 
 | 
 | ||||||
|  | 				call.signature = parseFunctionSignature(); | ||||||
| 				if (accept(SoltToken::Comma, true)) | 				if (accept(SoltToken::Comma, true)) | ||||||
| 					call.value = parseFunctionCallValue(); | 					call.value = parseFunctionCallValue(); | ||||||
| 				if (accept(SoltToken::Colon, true)) | 				if (accept(SoltToken::Colon, true)) | ||||||
| 					call.arguments = parseFunctionCallArguments(); | 					call.arguments = parseFunctionCallArguments(); | ||||||
| 
 | 
 | ||||||
| 				call.displayMode = parseNewline(); | 				if (accept(SoltToken::Newline, true)) | ||||||
|  | 					call.displayMode = FunctionCall::DisplayMode::MultiLine; | ||||||
|  | 
 | ||||||
| 				call.arguments.comment = parseComment(); | 				call.arguments.comment = parseComment(); | ||||||
| 
 | 
 | ||||||
| 				if (accept(SoltToken::Newline, true)) | 				if (accept(SoltToken::Newline, true)) | ||||||
| 					call.displayMode = FunctionCall::DisplayMode::MultiLine; | 					call.displayMode = FunctionCall::DisplayMode::MultiLine; | ||||||
|  | 
 | ||||||
| 				expect(SoltToken::Arrow); | 				expect(SoltToken::Arrow); | ||||||
| 
 |  | ||||||
| 				call.expectations = parseFunctionCallExpectations(); | 				call.expectations = parseFunctionCallExpectations(); | ||||||
| 
 |  | ||||||
| 				if (accept(SoltToken::Newline, false)) |  | ||||||
| 					call.displayMode = parseNewline(); |  | ||||||
| 				call.expectations.comment = parseComment(); | 				call.expectations.comment = parseComment(); | ||||||
| 
 | 
 | ||||||
| 				calls.emplace_back(std::move(call)); | 				calls.emplace_back(std::move(call)); | ||||||
| @ -121,8 +121,8 @@ bool TestFileParser::accept(SoltToken _token, bool const _expect) | |||||||
| bool TestFileParser::expect(SoltToken _token, bool const _advance) | bool TestFileParser::expect(SoltToken _token, bool const _advance) | ||||||
| { | { | ||||||
| 	if (m_scanner.currentToken() != _token) | 	if (m_scanner.currentToken() != _token) | ||||||
| 		throw Error | 		throw Error( | ||||||
| 			(Error::Type::ParserError, | 			Error::Type::ParserError, | ||||||
| 			"Unexpected " + formatToken(m_scanner.currentToken()) + ": \"" + | 			"Unexpected " + formatToken(m_scanner.currentToken()) + ": \"" + | ||||||
| 			m_scanner.currentLiteral() + "\". " + | 			m_scanner.currentLiteral() + "\". " + | ||||||
| 			"Expected \"" + formatToken(_token) + "\"." | 			"Expected \"" + formatToken(_token) + "\"." | ||||||
| @ -143,13 +143,13 @@ string TestFileParser::parseFunctionSignature() | |||||||
| 	while (!accept(SoltToken::RParen)) | 	while (!accept(SoltToken::RParen)) | ||||||
| 	{ | 	{ | ||||||
| 		signature += m_scanner.currentLiteral(); | 		signature += m_scanner.currentLiteral(); | ||||||
| 		expect(SoltToken::UInt); | 		expect(SoltToken::Identifier); | ||||||
| 		while (accept(SoltToken::Comma)) | 		while (accept(SoltToken::Comma)) | ||||||
| 		{ | 		{ | ||||||
| 			signature += m_scanner.currentLiteral(); | 			signature += m_scanner.currentLiteral(); | ||||||
| 			expect(SoltToken::Comma); | 			expect(SoltToken::Comma); | ||||||
| 			signature += m_scanner.currentLiteral(); | 			signature += m_scanner.currentLiteral(); | ||||||
| 			expect(SoltToken::UInt); | 			expect(SoltToken::Identifier); | ||||||
| 		} | 		} | ||||||
| 	} | 	} | ||||||
| 	signature += formatToken(SoltToken::RParen); | 	signature += formatToken(SoltToken::RParen); | ||||||
| @ -184,15 +184,18 @@ FunctionCallExpectations TestFileParser::parseFunctionCallExpectations() | |||||||
| 
 | 
 | ||||||
| 	auto param = parseParameter(); | 	auto param = parseParameter(); | ||||||
| 	if (param.abiType.type == ABIType::None) | 	if (param.abiType.type == ABIType::None) | ||||||
|  | 	{ | ||||||
|  | 		expectations.failure = false; | ||||||
| 		return expectations; | 		return expectations; | ||||||
| 	expectations.parameters.emplace_back(param); | 	} | ||||||
|  | 	expectations.result.emplace_back(param); | ||||||
| 
 | 
 | ||||||
| 	while (accept(SoltToken::Comma, true)) | 	while (accept(SoltToken::Comma, true)) | ||||||
| 		expectations.parameters.emplace_back(parseParameter()); | 		expectations.result.emplace_back(parseParameter()); | ||||||
| 
 | 
 | ||||||
| 	/// We have always one virtual parameter in the parameter list.
 | 	/// We have always one virtual parameter in the parameter list.
 | ||||||
| 	/// If its type is FAILURE, the expected result is also a REVERT etc.
 | 	/// If its type is FAILURE, the expected result is also a REVERT etc.
 | ||||||
| 	if (expectations.parameters.at(0).abiType.type != ABIType::Failure) | 	if (expectations.result.at(0).abiType.type != ABIType::Failure) | ||||||
| 		expectations.failure = false; | 		expectations.failure = false; | ||||||
| 	return expectations; | 	return expectations; | ||||||
| } | } | ||||||
| @ -212,8 +215,9 @@ pair<bytes, ABIType> TestFileParser::parseABITypeLiteral() | |||||||
| { | { | ||||||
| 	try | 	try | ||||||
| 	{ | 	{ | ||||||
| 		u256 number; | 		u256 number{0}; | ||||||
| 		ABIType abiType; | 		ABIType abiType{ABIType::None, 0}; | ||||||
|  | 
 | ||||||
| 		if (accept(SoltToken::Sub)) | 		if (accept(SoltToken::Sub)) | ||||||
| 		{ | 		{ | ||||||
| 			abiType = ABIType{ABIType::SignedDec, 32}; | 			abiType = ABIType{ABIType::SignedDec, 32}; | ||||||
| @ -227,7 +231,7 @@ pair<bytes, ABIType> TestFileParser::parseABITypeLiteral() | |||||||
| 				abiType = ABIType{ABIType::UnsignedDec, 32}; | 				abiType = ABIType{ABIType::UnsignedDec, 32}; | ||||||
| 				number = convertNumber(parseNumber()); | 				number = convertNumber(parseNumber()); | ||||||
| 			} | 			} | ||||||
| 			if (accept(SoltToken::Failure, true)) | 			else if (accept(SoltToken::Failure, true)) | ||||||
| 			{ | 			{ | ||||||
| 				abiType = ABIType{ABIType::Failure, 0}; | 				abiType = ABIType{ABIType::Failure, 0}; | ||||||
| 				return make_pair(bytes{}, abiType); | 				return make_pair(bytes{}, abiType); | ||||||
| @ -241,13 +245,6 @@ pair<bytes, ABIType> TestFileParser::parseABITypeLiteral() | |||||||
| 	} | 	} | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| solidity::test::FunctionCall::DisplayMode TestFileParser::parseNewline() |  | ||||||
| { |  | ||||||
| 	if (accept(SoltToken::Newline, true)) |  | ||||||
| 		return FunctionCall::DisplayMode::MultiLine; |  | ||||||
| 	return FunctionCall::DisplayMode::SingleLine; |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| string TestFileParser::parseComment() | string TestFileParser::parseComment() | ||||||
| { | { | ||||||
| 	string comment = m_scanner.currentLiteral(); | 	string comment = m_scanner.currentLiteral(); | ||||||
| @ -286,7 +283,6 @@ void TestFileParser::Scanner::scanNextToken() | |||||||
| { | { | ||||||
| 	auto detectToken = [](std::string const& _literal = "") -> TokenDesc { | 	auto detectToken = [](std::string const& _literal = "") -> TokenDesc { | ||||||
| 		if (_literal == "ether") return TokenDesc{SoltToken::Ether, _literal}; | 		if (_literal == "ether") return TokenDesc{SoltToken::Ether, _literal}; | ||||||
| 		if (_literal == "uint256") return TokenDesc{SoltToken::UInt, _literal}; |  | ||||||
| 		if (_literal == "FAILURE") return TokenDesc{SoltToken::Failure, _literal}; | 		if (_literal == "FAILURE") return TokenDesc{SoltToken::Failure, _literal}; | ||||||
| 		return TokenDesc{SoltToken::Identifier, _literal}; | 		return TokenDesc{SoltToken::Identifier, _literal}; | ||||||
| 	}; | 	}; | ||||||
| @ -336,9 +332,9 @@ void TestFileParser::Scanner::scanNextToken() | |||||||
| 				TokenDesc detectedToken = detectToken(scanIdentifierOrKeyword()); | 				TokenDesc detectedToken = detectToken(scanIdentifierOrKeyword()); | ||||||
| 				token = selectToken(detectedToken.first, detectedToken.second); | 				token = selectToken(detectedToken.first, detectedToken.second); | ||||||
| 			} | 			} | ||||||
| 			else if (isDecimalDigit(current())) | 			else if (isdigit(current())) | ||||||
| 				token = selectToken(SoltToken::Number, scanNumber()); | 				token = selectToken(SoltToken::Number, scanNumber()); | ||||||
| 			else if (isWhiteSpace(current())) | 			else if (isspace(current())) | ||||||
| 				token = selectToken(SoltToken::Whitespace); | 				token = selectToken(SoltToken::Whitespace); | ||||||
| 			else if (isEndOfLine()) | 			else if (isEndOfLine()) | ||||||
| 				token = selectToken(SoltToken::EOS); | 				token = selectToken(SoltToken::EOS); | ||||||
| @ -348,8 +344,6 @@ void TestFileParser::Scanner::scanNextToken() | |||||||
| 		} | 		} | ||||||
| 	} | 	} | ||||||
| 	while (token.first == SoltToken::Whitespace); | 	while (token.first == SoltToken::Whitespace); | ||||||
| 
 |  | ||||||
| 	m_nextToken = token; |  | ||||||
| 	m_currentToken = token; | 	m_currentToken = token; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| @ -382,7 +376,7 @@ string TestFileParser::Scanner::scanNumber() | |||||||
| { | { | ||||||
| 	string number; | 	string number; | ||||||
| 	number += current(); | 	number += current(); | ||||||
| 	while (isDecimalDigit(peek())) | 	while (isdigit(peek())) | ||||||
| 	{ | 	{ | ||||||
| 		advance(); | 		advance(); | ||||||
| 		number += current(); | 		number += current(); | ||||||
|  | |||||||
| @ -59,7 +59,6 @@ namespace test | |||||||
| 	T(Identifier, "identifier", 0) \ | 	T(Identifier, "identifier", 0) \ | ||||||
| 	/* type keywords */            \ | 	/* type keywords */            \ | ||||||
| 	K(Ether, "ether", 0)           \ | 	K(Ether, "ether", 0)           \ | ||||||
| 	K(UInt, "uint256", 0)          \ |  | ||||||
| 	/* special keywords */         \ | 	/* special keywords */         \ | ||||||
| 	K(Failure, "FAILURE", 0)       \ | 	K(Failure, "FAILURE", 0)       \ | ||||||
| 
 | 
 | ||||||
| @ -75,7 +74,9 @@ enum class SoltToken : unsigned int { | |||||||
|  * retrieved while parsing a test. This information is used |  * retrieved while parsing a test. This information is used | ||||||
|  * for the conversion of human-readable function arguments and |  * for the conversion of human-readable function arguments and | ||||||
|  * return values to `bytes` and vice-versa. |  * return values to `bytes` and vice-versa. | ||||||
|  * Defaults to an invalid 0-byte representation. |  * Defaults to None, a 0-byte representation. 0-bytes | ||||||
|  |  * can also be interpreted as Failure, which means | ||||||
|  |  * either a REVERT or another EVM failure. | ||||||
|  */ |  */ | ||||||
| struct ABIType | struct ABIType | ||||||
| { | { | ||||||
| @ -85,11 +86,8 @@ struct ABIType | |||||||
| 		Failure, | 		Failure, | ||||||
| 		None | 		None | ||||||
| 	}; | 	}; | ||||||
| 	ABIType(): type(ABIType::None), size(0) { } | 	Type type = ABIType::None; | ||||||
| 	ABIType(Type _type, size_t _size): type(_type), size(_size) { } | 	size_t size = 0; | ||||||
| 
 |  | ||||||
| 	Type type; |  | ||||||
| 	size_t size; |  | ||||||
| }; | }; | ||||||
| 
 | 
 | ||||||
| /**
 | /**
 | ||||||
| @ -102,17 +100,19 @@ struct FormatInfo | |||||||
| }; | }; | ||||||
| 
 | 
 | ||||||
| /**
 | /**
 | ||||||
|  * Parameter abstraction used for the encoding and decoding |  * Parameter abstraction used for the encoding and decoding of | ||||||
|  * function parameter lists and expectation lists. |  * function parameter and expectation / return value lists. | ||||||
|  * A parameter list is usually a comma-separated list of literals. |  * A parameter list is usually a comma-separated list of literals. | ||||||
|  * It should not be possible to call create a parameter holding |  * It should not be possible to call create a parameter holding | ||||||
|  * an identifier, but if so, the ABI type would be invalid. |  * an identifier, but if so, the ABI type would be invalid. | ||||||
|  */ |  */ | ||||||
| struct Parameter | struct Parameter | ||||||
| { | { | ||||||
| 	/// ABI encoded `bytes` of parsed expectations. This `bytes`
 | 	/// ABI encoded / decoded `bytes` of values.
 | ||||||
| 	/// is compared to the actual result of a function call
 | 	/// These `bytes` are used to pass values to function calls
 | ||||||
| 	/// and is taken into account while validating it.
 | 	/// and also to store expected return vales. These are
 | ||||||
|  | 	/// compared to the actual result of a function call
 | ||||||
|  | 	/// and used for validating it.
 | ||||||
| 	bytes rawBytes; | 	bytes rawBytes; | ||||||
| 	/// Types that were used to encode `rawBytes`. Expectations
 | 	/// Types that were used to encode `rawBytes`. Expectations
 | ||||||
| 	/// are usually comma separated literals. Their type is auto-
 | 	/// are usually comma separated literals. Their type is auto-
 | ||||||
| @ -133,21 +133,22 @@ using ParameterList = std::vector<Parameter>; | |||||||
|  */ |  */ | ||||||
| struct FunctionCallExpectations | struct FunctionCallExpectations | ||||||
| { | { | ||||||
| 	/// Representation of the comma-separated (or empty) list of expectation parameters given
 | 	/// Representation of the comma-separated (or empty) list of expectated result values
 | ||||||
| 	/// to a function call.
 | 	/// attached to the function call object. It is checked against the actual result of
 | ||||||
| 	ParameterList parameters; | 	/// a function call when used in test framework.
 | ||||||
|  | 	ParameterList result; | ||||||
| 	/// Expected status of the transaction. It can be either
 | 	/// Expected status of the transaction. It can be either
 | ||||||
| 	/// a REVERT or a different EVM failure (e.g. out-of-gas).
 | 	/// a REVERT or a different EVM failure (e.g. out-of-gas).
 | ||||||
| 	bool failure = true; | 	bool failure = true; | ||||||
| 	/// A Comment that can be attached to the expectations,
 | 	/// A Comment that can be attached to the expectations,
 | ||||||
| 	/// that is retained and can be displayed.
 | 	/// that is retained and can be displayed.
 | ||||||
| 	std::string comment; | 	std::string comment; | ||||||
| 	/// ABI encoded `bytes` of parsed parameters. This `bytes`
 | 	/// ABI encoded `bytes` of parsed expected return values. It is checked
 | ||||||
| 	/// passed to the function call.
 | 	/// against the actual result of a function call when used in test framework.
 | ||||||
| 	bytes rawBytes() const | 	bytes rawBytes() const | ||||||
| 	{ | 	{ | ||||||
| 		bytes raw; | 		bytes raw; | ||||||
| 		for (auto const& param: parameters) | 		for (auto const& param: result) | ||||||
| 			raw += param.rawBytes; | 			raw += param.rawBytes; | ||||||
| 		return raw; | 		return raw; | ||||||
| 	} | 	} | ||||||
| @ -168,7 +169,7 @@ struct FunctionCallArgs | |||||||
| 	/// A Comment that can be attached to the expectations,
 | 	/// A Comment that can be attached to the expectations,
 | ||||||
| 	/// that is retained and can be displayed.
 | 	/// that is retained and can be displayed.
 | ||||||
| 	std::string comment; | 	std::string comment; | ||||||
| 	/// ABI encoded `bytes` of parsed parameters. This `bytes`
 | 	/// ABI encoded `bytes` of parsed parameters. These `bytes`
 | ||||||
| 	/// passed to the function call.
 | 	/// passed to the function call.
 | ||||||
| 	bytes rawBytes() const | 	bytes rawBytes() const | ||||||
| 	{ | 	{ | ||||||
| @ -257,8 +258,6 @@ private: | |||||||
| 		void scanNextToken(); | 		void scanNextToken(); | ||||||
| 
 | 
 | ||||||
| 		SoltToken currentToken() { return m_currentToken.first; } | 		SoltToken currentToken() { return m_currentToken.first; } | ||||||
| 		SoltToken peekToken() { return m_nextToken.first; } |  | ||||||
| 
 |  | ||||||
| 		std::string currentLiteral() { return m_currentToken.second; } | 		std::string currentLiteral() { return m_currentToken.second; } | ||||||
| 
 | 
 | ||||||
| 		std::string scanComment(); | 		std::string scanComment(); | ||||||
| @ -283,7 +282,6 @@ private: | |||||||
| 		std::string m_currentLiteral; | 		std::string m_currentLiteral; | ||||||
| 
 | 
 | ||||||
| 		TokenDesc m_currentToken; | 		TokenDesc m_currentToken; | ||||||
| 		TokenDesc m_nextToken; |  | ||||||
| 	}; | 	}; | ||||||
| 
 | 
 | ||||||
| 	bool accept(SoltToken _token, bool const _expect = false); | 	bool accept(SoltToken _token, bool const _expect = false); | ||||||
| @ -321,10 +319,6 @@ private: | |||||||
| 	/// if data type is not supported.
 | 	/// if data type is not supported.
 | ||||||
| 	std::pair<bytes, ABIType> parseABITypeLiteral(); | 	std::pair<bytes, ABIType> parseABITypeLiteral(); | ||||||
| 
 | 
 | ||||||
| 	/// Accepts a newline `//` and returns DisplayMode::MultiLine
 |  | ||||||
| 	/// if found, DisplayMode::SingleLine otherwise.
 |  | ||||||
| 	FunctionCall::DisplayMode parseNewline(); |  | ||||||
| 
 |  | ||||||
| 	/// Parses a comment
 | 	/// Parses a comment
 | ||||||
| 	std::string parseComment(); | 	std::string parseComment(); | ||||||
| 
 | 
 | ||||||
|  | |||||||
| @ -23,7 +23,7 @@ | |||||||
| #include <tuple> | #include <tuple> | ||||||
| #include <boost/test/unit_test.hpp> | #include <boost/test/unit_test.hpp> | ||||||
| #include <liblangutil/Exceptions.h> | #include <liblangutil/Exceptions.h> | ||||||
| #include <test/libsolidity/SolidityExecutionFramework.h> | #include <test/ExecutionFramework.h> | ||||||
| 
 | 
 | ||||||
| #include <test/libsolidity/util/TestFileParser.h> | #include <test/libsolidity/util/TestFileParser.h> | ||||||
| 
 | 
 | ||||||
| @ -37,6 +37,9 @@ namespace solidity | |||||||
| namespace test | namespace test | ||||||
| { | { | ||||||
| 
 | 
 | ||||||
|  | using fmt = ExecutionFramework; | ||||||
|  | using Mode = FunctionCall::DisplayMode; | ||||||
|  | 
 | ||||||
| vector<FunctionCall> parse(string const& _source) | vector<FunctionCall> parse(string const& _source) | ||||||
| { | { | ||||||
| 	istringstream stream{_source, ios_base::out}; | 	istringstream stream{_source, ios_base::out}; | ||||||
| @ -44,51 +47,44 @@ vector<FunctionCall> parse(string const& _source) | |||||||
| 	return parser.parseFunctionCalls(); | 	return parser.parseFunctionCalls(); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | void testFunctionCall( | ||||||
|  | 		FunctionCall const& _call, | ||||||
|  | 		FunctionCall::DisplayMode _mode, | ||||||
|  | 		string _signature = "", | ||||||
|  | 		bool _failure = true, | ||||||
|  | 		bytes _arguments = bytes{}, | ||||||
|  | 		bytes _expectations = bytes{}, | ||||||
|  | 		u256 _value = 0, | ||||||
|  | 		string _argumentComment = "", | ||||||
|  | 		string _expectationComment = "" | ||||||
|  | ) | ||||||
|  | { | ||||||
|  | 	BOOST_REQUIRE_EQUAL(_call.expectations.failure, _failure); | ||||||
|  | 	BOOST_REQUIRE_EQUAL(_call.signature, _signature); | ||||||
|  | 	ABI_CHECK(_call.arguments.rawBytes(), _arguments); | ||||||
|  | 	ABI_CHECK(_call.expectations.rawBytes(), _expectations); | ||||||
|  | 	BOOST_REQUIRE_EQUAL(_call.displayMode, _mode); | ||||||
|  | 	BOOST_REQUIRE_EQUAL(_call.value, _value); | ||||||
|  | 	BOOST_REQUIRE_EQUAL(_call.arguments.comment, _argumentComment); | ||||||
|  | 	BOOST_REQUIRE_EQUAL(_call.expectations.comment, _expectationComment); | ||||||
|  | } | ||||||
|  | 
 | ||||||
| BOOST_AUTO_TEST_SUITE(TestFileParserTest) | BOOST_AUTO_TEST_SUITE(TestFileParserTest) | ||||||
| 
 | 
 | ||||||
| BOOST_AUTO_TEST_CASE(smoke_test) | BOOST_AUTO_TEST_CASE(smoke_test) | ||||||
| { | { | ||||||
| 	char const* source = R"()"; | 	char const* source = R"()"; | ||||||
| 	BOOST_CHECK_EQUAL(parse(source).size(), 0); | 	BOOST_REQUIRE_EQUAL(parse(source).size(), 0); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| BOOST_AUTO_TEST_CASE(simple_call_succees) | BOOST_AUTO_TEST_CASE(call_succees) | ||||||
| { | { | ||||||
| 	char const* source = R"( | 	char const* source = R"( | ||||||
| 		// f(uint256, uint256): 1, 1
 | 		// success() ->
 | ||||||
| 		// ->
 |  | ||||||
| 		// # This call should not return a value, but still succeed. #
 |  | ||||||
| 	)"; | 	)"; | ||||||
| 	auto const calls = parse(source); | 	auto const calls = parse(source); | ||||||
| 	BOOST_CHECK_EQUAL(calls.size(), 1); | 	BOOST_REQUIRE_EQUAL(calls.size(), 1); | ||||||
| 
 | 	testFunctionCall(calls.at(0), Mode::SingleLine, "success()", false); | ||||||
| 	auto call = calls.at(0); |  | ||||||
| 	BOOST_CHECK_EQUAL(call.displayMode, FunctionCall::DisplayMode::MultiLine); |  | ||||||
| 	BOOST_CHECK_EQUAL(call.signature, "f(uint256,uint256)"); |  | ||||||
| 	ABI_CHECK(call.arguments.rawBytes(), toBigEndian(u256{1}) + toBigEndian(u256{1})); |  | ||||||
| 	ABI_CHECK(call.expectations.rawBytes(), bytes{}); |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| BOOST_AUTO_TEST_CASE(simple_single_line_call_success) |  | ||||||
| { |  | ||||||
| 	char const* source = R"( |  | ||||||
| 		// f(uint256): 1 -> # Does not expect a value. #
 |  | ||||||
| 		// f(uint256): 1 -> 1 # Expect return value. #
 |  | ||||||
| 	)"; |  | ||||||
| 	auto const calls = parse(source); |  | ||||||
| 	BOOST_CHECK_EQUAL(calls.size(), 2); |  | ||||||
| 
 |  | ||||||
| 	auto call = calls.at(0); |  | ||||||
| 	BOOST_CHECK_EQUAL(call.signature, "f(uint256)"); |  | ||||||
| 	BOOST_CHECK_EQUAL(call.displayMode, FunctionCall::DisplayMode::SingleLine); |  | ||||||
| 	ABI_CHECK(call.arguments.rawBytes(), toBigEndian(u256{1})); |  | ||||||
| 	ABI_CHECK(call.expectations.rawBytes(), bytes{}); |  | ||||||
| 
 |  | ||||||
| 	call = calls.at(1); |  | ||||||
| 	BOOST_CHECK_EQUAL(call.signature, "f(uint256)"); |  | ||||||
| 	BOOST_CHECK_EQUAL(call.displayMode, FunctionCall::DisplayMode::SingleLine); |  | ||||||
| 	ABI_CHECK(call.arguments.rawBytes(), toBigEndian(u256{1})); |  | ||||||
| 	ABI_CHECK(call.expectations.rawBytes(), toBigEndian(u256{1})); |  | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| BOOST_AUTO_TEST_CASE(non_existent_call_revert_single_line) | BOOST_AUTO_TEST_CASE(non_existent_call_revert_single_line) | ||||||
| @ -97,31 +93,123 @@ BOOST_AUTO_TEST_CASE(non_existent_call_revert_single_line) | |||||||
| 		// i_am_not_there() -> FAILURE
 | 		// i_am_not_there() -> FAILURE
 | ||||||
| 	)"; | 	)"; | ||||||
| 	auto const calls = parse(source); | 	auto const calls = parse(source); | ||||||
| 	BOOST_CHECK_EQUAL(calls.size(), 1); | 	BOOST_REQUIRE_EQUAL(calls.size(), 1); | ||||||
|  | 	testFunctionCall(calls.at(0), Mode::SingleLine, "i_am_not_there()", true); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | BOOST_AUTO_TEST_CASE(call_arguments_success) | ||||||
|  | { | ||||||
|  | 	char const* source = R"( | ||||||
|  | 		// f(uint256): 1
 | ||||||
|  | 		// ->
 | ||||||
|  | 	)"; | ||||||
|  | 	auto const calls = parse(source); | ||||||
|  | 	BOOST_REQUIRE_EQUAL(calls.size(), 1); | ||||||
|  | 	testFunctionCall(calls.at(0), Mode::MultiLine, "f(uint256)", false, fmt::encodeArgs(u256{1})); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | BOOST_AUTO_TEST_CASE(call_arguments_comments_success) | ||||||
|  | { | ||||||
|  | 	char const* source = R"( | ||||||
|  | 		// f(uint256, uint256): 1, 1
 | ||||||
|  | 		// ->
 | ||||||
|  | 		// # This call should not return a value, but still succeed. #
 | ||||||
|  | 	)"; | ||||||
|  | 	auto const calls = parse(source); | ||||||
|  | 	BOOST_REQUIRE_EQUAL(calls.size(), 1); | ||||||
|  | 	testFunctionCall( | ||||||
|  | 		calls.at(0), | ||||||
|  | 		Mode::MultiLine, | ||||||
|  | 		"f(uint256,uint256)", | ||||||
|  | 		false, | ||||||
|  | 		fmt::encodeArgs(1, 1), | ||||||
|  | 		fmt::encodeArgs(), | ||||||
|  | 		0, | ||||||
|  | 		"", | ||||||
|  | 		" This call should not return a value, but still succeed. " | ||||||
|  | 	); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | BOOST_AUTO_TEST_CASE(simple_single_line_call_comment_success) | ||||||
|  | { | ||||||
|  | 	char const* source = R"( | ||||||
|  | 		// f(uint256): 1 -> # f(uint256) does not return a value. #
 | ||||||
|  | 		// f(uint256): 1 -> 1
 | ||||||
|  | 	)"; | ||||||
|  | 	auto const calls = parse(source); | ||||||
|  | 	BOOST_REQUIRE_EQUAL(calls.size(), 2); | ||||||
|  | 
 | ||||||
|  | 	testFunctionCall( | ||||||
|  | 		calls.at(0), | ||||||
|  | 		Mode::SingleLine, | ||||||
|  | 		"f(uint256)", | ||||||
|  | 		false, | ||||||
|  | 		fmt::encodeArgs(1), | ||||||
|  | 		fmt::encodeArgs(), | ||||||
|  | 		0, | ||||||
|  | 		"", | ||||||
|  | 		" f(uint256) does not return a value. " | ||||||
|  | 	); | ||||||
|  | 	testFunctionCall(calls.at(1), Mode::SingleLine, "f(uint256)", false, fmt::encode(1), fmt::encode(1)); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | BOOST_AUTO_TEST_CASE(multiple_single_line) | ||||||
|  | { | ||||||
|  | 	char const* source = R"( | ||||||
|  | 		// f(uint256): 1 -> 1
 | ||||||
|  | 		// g(uint256): 1 ->
 | ||||||
|  | 	)"; | ||||||
|  | 	auto const calls = parse(source); | ||||||
|  | 	BOOST_REQUIRE_EQUAL(calls.size(), 2); | ||||||
|  | 
 | ||||||
|  | 	testFunctionCall(calls.at(0), Mode::SingleLine, "f(uint256)", false, fmt::encodeArgs(1), fmt::encodeArgs(1)); | ||||||
|  | 	testFunctionCall(calls.at(1), Mode::SingleLine, "g(uint256)", false, fmt::encodeArgs(1)); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | BOOST_AUTO_TEST_CASE(multiple_single_line_swapped) | ||||||
|  | { | ||||||
|  | 	char const* source = R"( | ||||||
|  | 		// f(uint256): 1 ->
 | ||||||
|  | 		// g(uint256): 1 -> 1
 | ||||||
|  | 	)"; | ||||||
|  | 	auto const calls = parse(source); | ||||||
|  | 	BOOST_REQUIRE_EQUAL(calls.size(), 2); | ||||||
|  | 
 | ||||||
|  | 	testFunctionCall(calls.at(0), Mode::SingleLine, "f(uint256)", false, fmt::encodeArgs(1)); | ||||||
|  | 	testFunctionCall(calls.at(1), Mode::SingleLine, "g(uint256)", false, fmt::encodeArgs(1), fmt::encodeArgs(1)); | ||||||
| 
 | 
 | ||||||
| 	auto const& call = calls.at(0); |  | ||||||
| 	BOOST_CHECK_EQUAL(call.displayMode, FunctionCall::DisplayMode::SingleLine); |  | ||||||
| 	BOOST_CHECK_EQUAL(call.signature, "i_am_not_there()"); |  | ||||||
| 	BOOST_CHECK_EQUAL(call.expectations.failure, true); |  | ||||||
| 	BOOST_CHECK_EQUAL(call.expectations.parameters.at(0).abiType.type, ABIType::Failure); |  | ||||||
| 	ABI_CHECK(call.expectations.rawBytes(), bytes{}); |  | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| BOOST_AUTO_TEST_CASE(non_existent_call_revert) | BOOST_AUTO_TEST_CASE(non_existent_call_revert) | ||||||
| { | { | ||||||
| 	char const* source = R"( | 	char const* source = R"( | ||||||
| 		// i_am_not_there()
 | 		// i_am_not_there()
 | ||||||
| 		// -> FAILURE # This is can be either REVERT or a different EVM failure #
 | 		// -> FAILURE
 | ||||||
| 	)"; | 	)"; | ||||||
| 	auto const calls = parse(source); | 	auto const calls = parse(source); | ||||||
| 	BOOST_CHECK_EQUAL(calls.size(), 1); | 	BOOST_REQUIRE_EQUAL(calls.size(), 1); | ||||||
|  | 	testFunctionCall(calls.at(0), Mode::MultiLine, "i_am_not_there()", true); | ||||||
|  | } | ||||||
| 
 | 
 | ||||||
| 	auto const& call = calls.at(0); | BOOST_AUTO_TEST_CASE(call_expectations_empty_single_line) | ||||||
| 	BOOST_CHECK_EQUAL(call.displayMode, FunctionCall::DisplayMode::MultiLine); | { | ||||||
| 	BOOST_CHECK_EQUAL(call.signature, "i_am_not_there()"); | 	char const* source = R"( | ||||||
| 	BOOST_CHECK_EQUAL(call.expectations.parameters.at(0).abiType.type, ABIType::Failure); | 		// _exp_() ->
 | ||||||
| 	ABI_CHECK(call.expectations.rawBytes(), bytes{}); | 	)"; | ||||||
| 	BOOST_CHECK_EQUAL(call.expectations.failure, true); | 	auto const calls = parse(source); | ||||||
|  | 	BOOST_REQUIRE_EQUAL(calls.size(), 1); | ||||||
|  | 	testFunctionCall(calls.at(0), Mode::SingleLine, "_exp_()", false); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | BOOST_AUTO_TEST_CASE(call_expectations_empty_multiline) | ||||||
|  | { | ||||||
|  | 	char const* source = R"( | ||||||
|  | 		// _exp_()
 | ||||||
|  | 		// ->
 | ||||||
|  | 	)"; | ||||||
|  | 	auto const calls = parse(source); | ||||||
|  | 	BOOST_REQUIRE_EQUAL(calls.size(), 1); | ||||||
|  | 	testFunctionCall(calls.at(0), Mode::MultiLine, "_exp_()", false); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| BOOST_AUTO_TEST_CASE(call_comments) | BOOST_AUTO_TEST_CASE(call_comments) | ||||||
| @ -132,18 +220,29 @@ BOOST_AUTO_TEST_CASE(call_comments) | |||||||
| 		// -> 1 # Expectation comment #
 | 		// -> 1 # Expectation comment #
 | ||||||
| 	)"; | 	)"; | ||||||
| 	auto const calls = parse(source); | 	auto const calls = parse(source); | ||||||
| 	BOOST_CHECK_EQUAL(calls.size(), 2); | 	BOOST_REQUIRE_EQUAL(calls.size(), 2); | ||||||
| 
 | 	testFunctionCall( | ||||||
| 	BOOST_CHECK_EQUAL(calls.at(0).displayMode, FunctionCall::DisplayMode::SingleLine); | 		calls.at(0), | ||||||
| 	BOOST_CHECK_EQUAL(calls.at(1).displayMode, FunctionCall::DisplayMode::MultiLine); | 		Mode::SingleLine, | ||||||
| 
 | 		"f()", | ||||||
| 	for (auto const& call: calls) | 		false, | ||||||
| 	{ | 		fmt::encodeArgs(), | ||||||
| 		BOOST_CHECK_EQUAL(call.signature, "f()"); | 		fmt::encodeArgs(1), | ||||||
| 		BOOST_CHECK_EQUAL(call.arguments.comment, " Parameter comment "); | 		0, | ||||||
| 		BOOST_CHECK_EQUAL(call.expectations.comment, " Expectation comment "); | 		" Parameter comment ", | ||||||
| 		ABI_CHECK(call.expectations.rawBytes(), toBigEndian(u256{1})); | 		" Expectation comment " | ||||||
| 	} | 	); | ||||||
|  | 	testFunctionCall( | ||||||
|  | 		calls.at(1), | ||||||
|  | 		Mode::MultiLine, | ||||||
|  | 		"f()", | ||||||
|  | 		false, | ||||||
|  | 		fmt::encodeArgs(), | ||||||
|  | 		fmt::encodeArgs(1), | ||||||
|  | 		0, | ||||||
|  | 		" Parameter comment ", | ||||||
|  | 		" Expectation comment " | ||||||
|  | 	); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| BOOST_AUTO_TEST_CASE(call_arguments) | BOOST_AUTO_TEST_CASE(call_arguments) | ||||||
| @ -153,85 +252,17 @@ BOOST_AUTO_TEST_CASE(call_arguments) | |||||||
| 		// -> 4
 | 		// -> 4
 | ||||||
| 	)"; | 	)"; | ||||||
| 	auto const calls = parse(source); | 	auto const calls = parse(source); | ||||||
| 	BOOST_CHECK_EQUAL(calls.size(), 1); | 	BOOST_REQUIRE_EQUAL(calls.size(), 1); | ||||||
| 
 | 	testFunctionCall( | ||||||
| 	auto const& call = calls.at(0); | 		calls.at(0), | ||||||
| 	BOOST_CHECK_EQUAL(call.displayMode, FunctionCall::DisplayMode::MultiLine); | 		Mode::MultiLine, | ||||||
| 	BOOST_CHECK_EQUAL(call.signature, "f(uint256)"); | 		"f(uint256)", | ||||||
| 	BOOST_CHECK_EQUAL(call.value, u256{314}); | 		false, | ||||||
| 	BOOST_CHECK_EQUAL(call.expectations.failure, false); | 		fmt::encodeArgs(5), | ||||||
| 	ABI_CHECK(call.arguments.rawBytes(), toBigEndian(u256{5})); | 		fmt::encodeArgs(4), | ||||||
| 	ABI_CHECK(call.expectations.rawBytes(), toBigEndian(u256{4})); | 		314, | ||||||
| } | 		" optional ether value " | ||||||
| 
 | 	); | ||||||
| BOOST_AUTO_TEST_CASE(call_expectations_empty_single_line) |  | ||||||
| { |  | ||||||
| 	char const* source = R"( |  | ||||||
| 		// _exp_() ->
 |  | ||||||
| 	)"; |  | ||||||
| 	auto const calls = parse(source); |  | ||||||
| 	BOOST_CHECK_EQUAL(calls.size(), 1); |  | ||||||
| 
 |  | ||||||
| 	auto call = calls.at(0); |  | ||||||
| 	BOOST_CHECK_EQUAL(call.displayMode, FunctionCall::DisplayMode::SingleLine); |  | ||||||
| 	BOOST_CHECK_EQUAL(call.signature, "_exp_()"); |  | ||||||
| 	ABI_CHECK(call.arguments.rawBytes(), bytes{}); |  | ||||||
| 	ABI_CHECK(call.expectations.rawBytes(), bytes{}); |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| BOOST_AUTO_TEST_CASE(call_expectations_empty_multiline) |  | ||||||
| { |  | ||||||
| 	char const* source = R"( |  | ||||||
| 		// _exp_()
 |  | ||||||
| 		// ->
 |  | ||||||
| 		// # This call should not return a value, but still succeed. #
 |  | ||||||
| 	)"; |  | ||||||
| 	auto const calls = parse(source); |  | ||||||
| 	BOOST_CHECK_EQUAL(calls.size(), 1); |  | ||||||
| 
 |  | ||||||
| 	auto call = calls.at(0); |  | ||||||
| 	BOOST_CHECK_EQUAL(call.displayMode, FunctionCall::DisplayMode::MultiLine); |  | ||||||
| 	BOOST_CHECK_EQUAL(call.signature, "_exp_()"); |  | ||||||
| 	ABI_CHECK(call.arguments.rawBytes(), bytes{}); |  | ||||||
| 	ABI_CHECK(call.expectations.rawBytes(), bytes{}); |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| BOOST_AUTO_TEST_CASE(call_expectations_missing) |  | ||||||
| { |  | ||||||
| 	char const* source = R"( |  | ||||||
| 		// f())";
 |  | ||||||
| 	BOOST_CHECK_THROW(parse(source), langutil::Error); |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| BOOST_AUTO_TEST_CASE(call_ether_value_expectations_missing) |  | ||||||
| { |  | ||||||
| 	char const* source = R"( |  | ||||||
| 		// f(), 0)";
 |  | ||||||
| 	BOOST_CHECK_THROW(parse(source), langutil::Error); |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| BOOST_AUTO_TEST_CASE(call_arguments_invalid) |  | ||||||
| { |  | ||||||
| 	char const* source = R"( |  | ||||||
| 		// f(uint256): abc -> 1
 |  | ||||||
| 	)"; |  | ||||||
| 	BOOST_CHECK_THROW(parse(source), langutil::Error); |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| BOOST_AUTO_TEST_CASE(call_ether_value_invalid) |  | ||||||
| { |  | ||||||
| 	char const* source = R"( |  | ||||||
| 		// f(uint256), abc : 1 -> 1
 |  | ||||||
| 	)"; |  | ||||||
| 	BOOST_CHECK_THROW(parse(source), langutil::Error); |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| BOOST_AUTO_TEST_CASE(call_ether_type_invalid) |  | ||||||
| { |  | ||||||
| 	char const* source = R"( |  | ||||||
| 		// f(uint256), 2 btc : 1 -> 1
 |  | ||||||
| 	)"; |  | ||||||
| 	BOOST_CHECK_THROW(parse(source), langutil::Error); |  | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| BOOST_AUTO_TEST_CASE(call_arguments_mismatch) | BOOST_AUTO_TEST_CASE(call_arguments_mismatch) | ||||||
| @ -243,13 +274,17 @@ BOOST_AUTO_TEST_CASE(call_arguments_mismatch) | |||||||
| 		// -> 1
 | 		// -> 1
 | ||||||
| 	)"; | 	)"; | ||||||
| 	auto const calls = parse(source); | 	auto const calls = parse(source); | ||||||
| 	BOOST_CHECK_EQUAL(calls.size(), 1); | 	BOOST_REQUIRE_EQUAL(calls.size(), 1); | ||||||
| 
 | 	testFunctionCall( | ||||||
| 	auto const& call = calls.at(0); | 		calls.at(0), | ||||||
| 	BOOST_CHECK_EQUAL(call.displayMode, FunctionCall::DisplayMode::MultiLine); | 		Mode::MultiLine, | ||||||
| 	BOOST_CHECK_EQUAL(call.signature, "f(uint256)"); | 		"f(uint256)", | ||||||
| 	ABI_CHECK(call.arguments.rawBytes(), toBigEndian(u256{1}) + toBigEndian(u256{2})); | 		false, | ||||||
| 	BOOST_CHECK_EQUAL(call.expectations.failure, false); | 		fmt::encodeArgs(1, 2), | ||||||
|  | 		fmt::encodeArgs(1), | ||||||
|  | 		0, | ||||||
|  | 		" This only throws at runtime " | ||||||
|  | 	); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| BOOST_AUTO_TEST_CASE(call_multiple_arguments) | BOOST_AUTO_TEST_CASE(call_multiple_arguments) | ||||||
| @ -262,13 +297,15 @@ BOOST_AUTO_TEST_CASE(call_multiple_arguments) | |||||||
| 		// 1
 | 		// 1
 | ||||||
| 	)"; | 	)"; | ||||||
| 	auto const calls = parse(source); | 	auto const calls = parse(source); | ||||||
| 	BOOST_CHECK_EQUAL(calls.size(), 1); | 	BOOST_REQUIRE_EQUAL(calls.size(), 1); | ||||||
| 
 | 	testFunctionCall( | ||||||
| 	auto const& call = calls.at(0); | 		calls.at(0), | ||||||
| 	BOOST_CHECK_EQUAL(call.displayMode, FunctionCall::DisplayMode::MultiLine); | 		Mode::MultiLine, | ||||||
| 	BOOST_CHECK_EQUAL(call.signature, "test(uint256,uint256)"); | 		"test(uint256,uint256)", | ||||||
| 	ABI_CHECK(call.arguments.rawBytes(), toBigEndian(u256{1}) + toBigEndian(u256{2})); | 		false, | ||||||
| 	BOOST_CHECK_EQUAL(call.expectations.failure, false); | 		fmt::encodeArgs(1, 2), | ||||||
|  | 		fmt::encodeArgs(1, 1) | ||||||
|  | 	); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| BOOST_AUTO_TEST_CASE(call_multiple_arguments_mixed_format) | BOOST_AUTO_TEST_CASE(call_multiple_arguments_mixed_format) | ||||||
| @ -279,15 +316,74 @@ BOOST_AUTO_TEST_CASE(call_multiple_arguments_mixed_format) | |||||||
| 		// -> -1, 2
 | 		// -> -1, 2
 | ||||||
| 	)"; | 	)"; | ||||||
| 	auto const calls = parse(source); | 	auto const calls = parse(source); | ||||||
| 	BOOST_CHECK_EQUAL(calls.size(), 1); | 	BOOST_REQUIRE_EQUAL(calls.size(), 1); | ||||||
|  | 	testFunctionCall( | ||||||
|  | 		calls.at(0), | ||||||
|  | 		Mode::MultiLine, | ||||||
|  | 		"test(uint256,uint256)", | ||||||
|  | 		false, | ||||||
|  | 		fmt::encodeArgs(1, -2), | ||||||
|  | 		fmt::encodeArgs(-1, 2), | ||||||
|  | 		314 | ||||||
|  | 	); | ||||||
|  | } | ||||||
| 
 | 
 | ||||||
| 	auto const& call = calls.at(0); | BOOST_AUTO_TEST_CASE(call_signature) | ||||||
| 	BOOST_CHECK_EQUAL(call.displayMode, FunctionCall::DisplayMode::MultiLine); | { | ||||||
| 	BOOST_CHECK_EQUAL(call.signature, "test(uint256,uint256)"); | 	char const* source = R"( | ||||||
| 	BOOST_CHECK_EQUAL(call.value, u256{314}); | 		// f(uint256, uint8, string) -> FAILURE
 | ||||||
| 	ABI_CHECK(call.arguments.rawBytes(), toBigEndian(u256{1}) + toBigEndian(u256{-2})); | 		// f(invalid, xyz, foo) -> FAILURE
 | ||||||
| 	BOOST_CHECK_EQUAL(call.expectations.failure, false); | 		)"; | ||||||
| 	ABI_CHECK(call.expectations.rawBytes(), toBigEndian(u256{-1}) + toBigEndian(u256{2})); | 	auto const calls = parse(source); | ||||||
|  | 	BOOST_REQUIRE_EQUAL(calls.size(), 2); | ||||||
|  | 	testFunctionCall(calls.at(0), Mode::SingleLine, "f(uint256,uint8,string)", true); | ||||||
|  | 	testFunctionCall(calls.at(1), Mode::SingleLine, "f(invalid,xyz,foo)", true); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | BOOST_AUTO_TEST_CASE(call_signature_invalid) | ||||||
|  | { | ||||||
|  | 	char const* source = R"( | ||||||
|  | 		// f(uint8,) -> FAILURE
 | ||||||
|  | 		)"; | ||||||
|  | 	BOOST_REQUIRE_THROW(parse(source), langutil::Error); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | BOOST_AUTO_TEST_CASE(call_expectations_missing) | ||||||
|  | { | ||||||
|  | 	char const* source = R"( | ||||||
|  | 		// f())";
 | ||||||
|  | 	BOOST_REQUIRE_THROW(parse(source), langutil::Error); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | BOOST_AUTO_TEST_CASE(call_ether_value_expectations_missing) | ||||||
|  | { | ||||||
|  | 	char const* source = R"( | ||||||
|  | 		// f(), 0)";
 | ||||||
|  | 	BOOST_REQUIRE_THROW(parse(source), langutil::Error); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | BOOST_AUTO_TEST_CASE(call_arguments_invalid) | ||||||
|  | { | ||||||
|  | 	char const* source = R"( | ||||||
|  | 		// f(uint256): abc -> 1
 | ||||||
|  | 	)"; | ||||||
|  | 	BOOST_REQUIRE_THROW(parse(source), langutil::Error); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | BOOST_AUTO_TEST_CASE(call_ether_value_invalid) | ||||||
|  | { | ||||||
|  | 	char const* source = R"( | ||||||
|  | 		// f(uint256), abc : 1 -> 1
 | ||||||
|  | 	)"; | ||||||
|  | 	BOOST_REQUIRE_THROW(parse(source), langutil::Error); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | BOOST_AUTO_TEST_CASE(call_ether_type_invalid) | ||||||
|  | { | ||||||
|  | 	char const* source = R"( | ||||||
|  | 		// f(uint256), 2 btc : 1 -> 1
 | ||||||
|  | 	)"; | ||||||
|  | 	BOOST_REQUIRE_THROW(parse(source), langutil::Error); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| BOOST_AUTO_TEST_CASE(call_arguments_colon) | BOOST_AUTO_TEST_CASE(call_arguments_colon) | ||||||
| @ -296,7 +392,7 @@ BOOST_AUTO_TEST_CASE(call_arguments_colon) | |||||||
| 		// h256():
 | 		// h256():
 | ||||||
| 		// -> 1
 | 		// -> 1
 | ||||||
| 	)"; | 	)"; | ||||||
| 	BOOST_CHECK_THROW(parse(source), langutil::Error); | 	BOOST_REQUIRE_THROW(parse(source), langutil::Error); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| BOOST_AUTO_TEST_CASE(call_arguments_newline_colon) | BOOST_AUTO_TEST_CASE(call_arguments_newline_colon) | ||||||
| @ -306,11 +402,9 @@ BOOST_AUTO_TEST_CASE(call_arguments_newline_colon) | |||||||
| 		// :
 | 		// :
 | ||||||
| 		// -> 1
 | 		// -> 1
 | ||||||
| 	)"; | 	)"; | ||||||
| 	BOOST_CHECK_THROW(parse(source), langutil::Error); | 	BOOST_REQUIRE_THROW(parse(source), langutil::Error); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| 
 |  | ||||||
| 
 |  | ||||||
| BOOST_AUTO_TEST_SUITE_END() | BOOST_AUTO_TEST_SUITE_END() | ||||||
| 
 | 
 | ||||||
| } | } | ||||||
|  | |||||||
		Loading…
	
		Reference in New Issue
	
	Block a user