diff options
author | Paweł Bylica <pawel.bylica@imapp.pl> | 2014-12-05 22:10:46 +0800 |
---|---|---|
committer | Paweł Bylica <pawel.bylica@imapp.pl> | 2014-12-05 22:10:46 +0800 |
commit | a03d5e5dc2b7cbda5480da3c893b14a79b9e8c4c (patch) | |
tree | 858ac2df63dd620b0a962a48c02f0fbe5e10b152 | |
parent | 421b5ccc362cf145cd214985240fa2a0848cd026 (diff) | |
parent | 80ad71576459f0401d838aa97b62bc40607dbafb (diff) | |
download | dexon-solidity-a03d5e5dc2b7cbda5480da3c893b14a79b9e8c4c.tar.gz dexon-solidity-a03d5e5dc2b7cbda5480da3c893b14a79b9e8c4c.tar.zst dexon-solidity-a03d5e5dc2b7cbda5480da3c893b14a79b9e8c4c.zip |
Merge remote-tracking branch 'upstream/develop' into develop-evmcc
-rw-r--r-- | solidityJSONInterfaceTest.cpp | 43 | ||||
-rw-r--r-- | solidityNatspecJSON.cpp | 400 |
2 files changed, 429 insertions, 14 deletions
diff --git a/solidityJSONInterfaceTest.cpp b/solidityJSONInterfaceTest.cpp index 1a443087..407f05d0 100644 --- a/solidityJSONInterfaceTest.cpp +++ b/solidityJSONInterfaceTest.cpp @@ -23,6 +23,7 @@ #include <boost/test/unit_test.hpp> #include <libsolidity/CompilerStack.h> #include <jsonrpc/json/json.h> +#include <libdevcore/Exceptions.h> namespace dev { @@ -34,23 +35,37 @@ namespace test class InterfaceChecker { public: - bool checkInterface(std::string const& _code, std::string const& _expectedInterfaceString) + void checkInterface(std::string const& _code, std::string const& _expectedInterfaceString) { - m_compilerStack.parse(_code); - std::string generatedInterfaceString = m_compilerStack.getInterface(); + try + { + m_compilerStack.parse(_code); + } + catch (const std::exception& e) + { + std::string const* extra = boost::get_error_info<errinfo_comment>(e); + std::string msg = std::string("Parsing contract failed with: ") + + e.what() + std::string("\n"); + if (extra) + msg += *extra; + BOOST_FAIL(msg); + } + std::string generatedInterfaceString = m_compilerStack.getJsonDocumentation(ABI_INTERFACE); Json::Value generatedInterface; m_reader.parse(generatedInterfaceString, generatedInterface); Json::Value expectedInterface; m_reader.parse(_expectedInterfaceString, expectedInterface); - return expectedInterface == generatedInterface; + BOOST_CHECK_MESSAGE(expectedInterface == generatedInterface, + "Expected " << _expectedInterfaceString << + "\n but got:\n" << generatedInterfaceString); } - + private: CompilerStack m_compilerStack; Json::Reader m_reader; }; -BOOST_FIXTURE_TEST_SUITE(SolidityCompilerJSONInterfaceOutput, InterfaceChecker) +BOOST_FIXTURE_TEST_SUITE(SolidityABIJSON, InterfaceChecker) BOOST_AUTO_TEST_CASE(basic_test) { @@ -76,7 +91,7 @@ BOOST_AUTO_TEST_CASE(basic_test) } ])"; - BOOST_CHECK(checkInterface(sourceCode, interface)); + checkInterface(sourceCode, interface); } BOOST_AUTO_TEST_CASE(empty_contract) @@ -86,7 +101,7 @@ BOOST_AUTO_TEST_CASE(empty_contract) char const* interface = "[]"; - BOOST_CHECK(checkInterface(sourceCode, interface)); + checkInterface(sourceCode, interface); } BOOST_AUTO_TEST_CASE(multiple_methods) @@ -95,7 +110,7 @@ BOOST_AUTO_TEST_CASE(multiple_methods) " function f(uint a) returns(uint d) { return a * 7; }\n" " function g(uint b) returns(uint e) { return b * 8; }\n" "}\n"; - + char const* interface = R"([ { "name": "f", @@ -129,7 +144,7 @@ BOOST_AUTO_TEST_CASE(multiple_methods) } ])"; - BOOST_CHECK(checkInterface(sourceCode, interface)); + checkInterface(sourceCode, interface); } BOOST_AUTO_TEST_CASE(multiple_params) @@ -160,7 +175,7 @@ BOOST_AUTO_TEST_CASE(multiple_params) } ])"; - BOOST_CHECK(checkInterface(sourceCode, interface)); + checkInterface(sourceCode, interface); } BOOST_AUTO_TEST_CASE(multiple_methods_order) @@ -170,7 +185,7 @@ BOOST_AUTO_TEST_CASE(multiple_methods_order) " function f(uint a) returns(uint d) { return a * 7; }\n" " function c(uint b) returns(uint e) { return b * 8; }\n" "}\n"; - + char const* interface = R"([ { "name": "c", @@ -203,8 +218,8 @@ BOOST_AUTO_TEST_CASE(multiple_methods_order) ] } ])"; - - BOOST_CHECK(checkInterface(sourceCode, interface)); + + checkInterface(sourceCode, interface); } BOOST_AUTO_TEST_SUITE_END() diff --git a/solidityNatspecJSON.cpp b/solidityNatspecJSON.cpp new file mode 100644 index 00000000..2ccedf7a --- /dev/null +++ b/solidityNatspecJSON.cpp @@ -0,0 +1,400 @@ +/* + This file is part of cpp-ethereum. + + cpp-ethereum is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + cpp-ethereum is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with cpp-ethereum. If not, see <http://www.gnu.org/licenses/>. + */ +/** + * @author Lefteris Karapetsas <lefteris@ethdev.com> + * @date 2014 + * Unit tests for the solidity compiler JSON Interface output. + */ + +#include <boost/test/unit_test.hpp> +#include <libsolidity/CompilerStack.h> +#include <jsonrpc/json/json.h> +#include <libdevcore/Exceptions.h> + +namespace dev +{ +namespace solidity +{ +namespace test +{ + +class DocumentationChecker +{ +public: + void checkNatspec(std::string const& _code, + std::string const& _expectedDocumentationString, + bool _userDocumentation) + { + std::string generatedDocumentationString; + try + { + m_compilerStack.parse(_code); + } + catch (const std::exception& e) + { + std::string const* extra = boost::get_error_info<errinfo_comment>(e); + std::string msg = std::string("Parsing contract failed with: ") + + e.what() + std::string("\n"); + if (extra) + msg += *extra; + BOOST_FAIL(msg); + } + + if (_userDocumentation) + generatedDocumentationString = m_compilerStack.getJsonDocumentation(NATSPEC_USER); + else + generatedDocumentationString = m_compilerStack.getJsonDocumentation(NATSPEC_DEV); + Json::Value generatedDocumentation; + m_reader.parse(generatedDocumentationString, generatedDocumentation); + Json::Value expectedDocumentation; + m_reader.parse(_expectedDocumentationString, expectedDocumentation); + BOOST_CHECK_MESSAGE(expectedDocumentation == generatedDocumentation, + "Expected " << _expectedDocumentationString << + "\n but got:\n" << generatedDocumentationString); + } + +private: + CompilerStack m_compilerStack; + Json::Reader m_reader; +}; + +BOOST_FIXTURE_TEST_SUITE(SolidityNatspecJSON, DocumentationChecker) + +BOOST_AUTO_TEST_CASE(user_basic_test) +{ + char const* sourceCode = "contract test {\n" + " /// @notice Multiplies `a` by 7\n" + " function mul(uint a) returns(uint d) { return a * 7; }\n" + "}\n"; + + char const* natspec = "{" + "\"methods\":{" + " \"mul\":{ \"notice\": \"Multiplies `a` by 7\"}" + "}}"; + + checkNatspec(sourceCode, natspec, true); +} + +BOOST_AUTO_TEST_CASE(dev_and_user_basic_test) +{ + char const* sourceCode = "contract test {\n" + " /// @notice Multiplies `a` by 7\n" + " /// @dev Multiplies a number by 7\n" + " function mul(uint a) returns(uint d) { return a * 7; }\n" + "}\n"; + + char const* devNatspec = "{" + "\"methods\":{" + " \"mul\":{ \n" + " \"details\": \"Multiplies a number by 7\"\n" + " }\n" + " }\n" + "}}"; + + char const* userNatspec = "{" + "\"methods\":{" + " \"mul\":{ \"notice\": \"Multiplies `a` by 7\"}" + "}}"; + + checkNatspec(sourceCode, devNatspec, false); + checkNatspec(sourceCode, userNatspec, true); +} + +BOOST_AUTO_TEST_CASE(user_multiline_comment) +{ + char const* sourceCode = "contract test {\n" + " /// @notice Multiplies `a` by 7\n" + " /// and then adds `b`\n" + " function mul_and_add(uint a, uint256 b) returns(uint256 d)\n" + " {\n" + " return (a * 7) + b;\n" + " }\n" + "}\n"; + + char const* natspec = "{" + "\"methods\":{" + " \"mul_and_add\":{ \"notice\": \"Multiplies `a` by 7 and then adds `b`\"}" + "}}"; + + checkNatspec(sourceCode, natspec, true); +} + +BOOST_AUTO_TEST_CASE(user_multiple_functions) +{ + char const* sourceCode = "contract test {\n" + " /// @notice Multiplies `a` by 7 and then adds `b`\n" + " function mul_and_add(uint a, uint256 b) returns(uint256 d)\n" + " {\n" + " return (a * 7) + b;\n" + " }\n" + "\n" + " /// @notice Divides `input` by `div`\n" + " function divide(uint input, uint div) returns(uint d)\n" + " {\n" + " return input / div;\n" + " }\n" + " /// @notice Subtracts 3 from `input`\n" + " function sub(int input) returns(int d)\n" + " {\n" + " return input - 3;\n" + " }\n" + "}\n"; + + char const* natspec = "{" + "\"methods\":{" + " \"mul_and_add\":{ \"notice\": \"Multiplies `a` by 7 and then adds `b`\"}," + " \"divide\":{ \"notice\": \"Divides `input` by `div`\"}," + " \"sub\":{ \"notice\": \"Subtracts 3 from `input`\"}" + "}}"; + + checkNatspec(sourceCode, natspec, true); +} + +BOOST_AUTO_TEST_CASE(user_empty_contract) +{ + char const* sourceCode = "contract test {\n" + "}\n"; + + char const* natspec = "{\"methods\":{} }"; + + checkNatspec(sourceCode, natspec, true); +} + +BOOST_AUTO_TEST_CASE(dev_and_user_no_doc) +{ + char const* sourceCode = "contract test {\n" + " function mul(uint a) returns(uint d) { return a * 7; }\n" + " function sub(int input) returns(int d)\n" + " {\n" + " return input - 3;\n" + " }\n" + "}\n"; + + char const* devNatspec = "{\"methods\":{}}"; + + char const* userNatspec = "{\"methods\":{}}"; + + checkNatspec(sourceCode, devNatspec, false); + checkNatspec(sourceCode, userNatspec, true); +} + +BOOST_AUTO_TEST_CASE(dev_desc_after_nl) +{ + char const* sourceCode = "contract test {\n" + " /// @dev\n" + " /// Multiplies a number by 7 and adds second parameter\n" + " /// @param a Documentation for the first parameter\n" + " /// @param second Documentation for the second parameter\n" + " function mul(uint a, uint second) returns(uint d) { return a * 7 + second; }\n" + "}\n"; + + char const* natspec = "{" + "\"methods\":{" + " \"mul\":{ \n" + " \"details\": \" Multiplies a number by 7 and adds second parameter\",\n" + " \"params\": {\n" + " \"a\": \"Documentation for the first parameter\",\n" + " \"second\": \"Documentation for the second parameter\"\n" + " }\n" + " }\n" + "}}"; + + checkNatspec(sourceCode, natspec, false); +} + +BOOST_AUTO_TEST_CASE(dev_multiple_params) +{ + char const* sourceCode = "contract test {\n" + " /// @dev Multiplies a number by 7 and adds second parameter\n" + " /// @param a Documentation for the first parameter\n" + " /// @param second Documentation for the second parameter\n" + " function mul(uint a, uint second) returns(uint d) { return a * 7 + second; }\n" + "}\n"; + + char const* natspec = "{" + "\"methods\":{" + " \"mul\":{ \n" + " \"details\": \"Multiplies a number by 7 and adds second parameter\",\n" + " \"params\": {\n" + " \"a\": \"Documentation for the first parameter\",\n" + " \"second\": \"Documentation for the second parameter\"\n" + " }\n" + " }\n" + "}}"; + + checkNatspec(sourceCode, natspec, false); +} + +BOOST_AUTO_TEST_CASE(dev_mutiline_param_description) +{ + char const* sourceCode = "contract test {\n" + " /// @dev Multiplies a number by 7 and adds second parameter\n" + " /// @param a Documentation for the first parameter starts here.\n" + " /// Since it's a really complicated parameter we need 2 lines\n" + " /// @param second Documentation for the second parameter\n" + " function mul(uint a, uint second) returns(uint d) { return a * 7 + second; }\n" + "}\n"; + + char const* natspec = "{" + "\"methods\":{" + " \"mul\":{ \n" + " \"details\": \"Multiplies a number by 7 and adds second parameter\",\n" + " \"params\": {\n" + " \"a\": \"Documentation for the first parameter starts here. Since it's a really complicated parameter we need 2 lines\",\n" + " \"second\": \"Documentation for the second parameter\"\n" + " }\n" + " }\n" + "}}"; + + checkNatspec(sourceCode, natspec, false); +} + +BOOST_AUTO_TEST_CASE(dev_multiple_functions) +{ + char const* sourceCode = "contract test {\n" + " /// @dev Multiplies a number by 7 and adds second parameter\n" + " /// @param a Documentation for the first parameter\n" + " /// @param second Documentation for the second parameter\n" + " function mul(uint a, uint second) returns(uint d) { return a * 7 + second; }\n" + " \n" + " /// @dev Divides 2 numbers\n" + " /// @param input Documentation for the input parameter\n" + " /// @param div Documentation for the div parameter\n" + " function divide(uint input, uint div) returns(uint d)\n" + " {\n" + " return input / div;\n" + " }\n" + " /// @dev Subtracts 3 from `input`\n" + " /// @param input Documentation for the input parameter\n" + " function sub(int input) returns(int d)\n" + " {\n" + " return input - 3;\n" + " }\n" + "}\n"; + + char const* natspec = "{" + "\"methods\":{" + " \"mul\":{ \n" + " \"details\": \"Multiplies a number by 7 and adds second parameter\",\n" + " \"params\": {\n" + " \"a\": \"Documentation for the first parameter\",\n" + " \"second\": \"Documentation for the second parameter\"\n" + " }\n" + " },\n" + " \"divide\":{ \n" + " \"details\": \"Divides 2 numbers\",\n" + " \"params\": {\n" + " \"input\": \"Documentation for the input parameter\",\n" + " \"div\": \"Documentation for the div parameter\"\n" + " }\n" + " },\n" + " \"sub\":{ \n" + " \"details\": \"Subtracts 3 from `input`\",\n" + " \"params\": {\n" + " \"input\": \"Documentation for the input parameter\"\n" + " }\n" + " }\n" + "}}"; + + checkNatspec(sourceCode, natspec, false); +} + +BOOST_AUTO_TEST_CASE(dev_return) +{ + char const* sourceCode = "contract test {\n" + " /// @dev Multiplies a number by 7 and adds second parameter\n" + " /// @param a Documentation for the first parameter starts here.\n" + " /// Since it's a really complicated parameter we need 2 lines\n" + " /// @param second Documentation for the second parameter\n" + " /// @return The result of the multiplication\n" + " function mul(uint a, uint second) returns(uint d) { return a * 7 + second; }\n" + "}\n"; + + char const* natspec = "{" + "\"methods\":{" + " \"mul\":{ \n" + " \"details\": \"Multiplies a number by 7 and adds second parameter\",\n" + " \"params\": {\n" + " \"a\": \"Documentation for the first parameter starts here. Since it's a really complicated parameter we need 2 lines\",\n" + " \"second\": \"Documentation for the second parameter\"\n" + " },\n" + " \"return\": \"The result of the multiplication\"\n" + " }\n" + "}}"; + + checkNatspec(sourceCode, natspec, false); +} +BOOST_AUTO_TEST_CASE(dev_return_desc_after_nl) +{ + char const* sourceCode = "contract test {\n" + " /// @dev Multiplies a number by 7 and adds second parameter\n" + " /// @param a Documentation for the first parameter starts here.\n" + " /// Since it's a really complicated parameter we need 2 lines\n" + " /// @param second Documentation for the second parameter\n" + " /// @return\n" + " /// The result of the multiplication\n" + " function mul(uint a, uint second) returns(uint d) { return a * 7 + second; }\n" + "}\n"; + + char const* natspec = "{" + "\"methods\":{" + " \"mul\":{ \n" + " \"details\": \"Multiplies a number by 7 and adds second parameter\",\n" + " \"params\": {\n" + " \"a\": \"Documentation for the first parameter starts here. Since it's a really complicated parameter we need 2 lines\",\n" + " \"second\": \"Documentation for the second parameter\"\n" + " },\n" + " \"return\": \" The result of the multiplication\"\n" + " }\n" + "}}"; + + checkNatspec(sourceCode, natspec, false); +} + + +BOOST_AUTO_TEST_CASE(dev_multiline_return) +{ + char const* sourceCode = "contract test {\n" + " /// @dev Multiplies a number by 7 and adds second parameter\n" + " /// @param a Documentation for the first parameter starts here.\n" + " /// Since it's a really complicated parameter we need 2 lines\n" + " /// @param second Documentation for the second parameter\n" + " /// @return The result of the multiplication\n" + " /// and cookies with nutella\n" + " function mul(uint a, uint second) returns(uint d) { return a * 7 + second; }\n" + "}\n"; + + char const* natspec = "{" + "\"methods\":{" + " \"mul\":{ \n" + " \"details\": \"Multiplies a number by 7 and adds second parameter\",\n" + " \"params\": {\n" + " \"a\": \"Documentation for the first parameter starts here. Since it's a really complicated parameter we need 2 lines\",\n" + " \"second\": \"Documentation for the second parameter\"\n" + " },\n" + " \"return\": \"The result of the multiplication and cookies with nutella\"\n" + " }\n" + "}}"; + + checkNatspec(sourceCode, natspec, false); +} + +BOOST_AUTO_TEST_SUITE_END() + +} +} +} |