diff --git a/libsolidity/CompilerStack.cpp b/libsolidity/CompilerStack.cpp index e25438f7c..77a019b5f 100644 --- a/libsolidity/CompilerStack.cpp +++ b/libsolidity/CompilerStack.cpp @@ -134,7 +134,7 @@ string const& CompilerStack::getDocumentation() if (m_documentation.empty()) { Json::Value doc; - Json::Value methods; + Json::Value methods(Json::objectValue); vector exportedFunctions = m_contractASTNode->getInterfaceFunctions(); for (FunctionDefinition const* f: exportedFunctions) diff --git a/test/solidityJSONInterfaceTest.cpp b/test/solidityJSONInterfaceTest.cpp index b91880130..f46a3ad36 100644 --- a/test/solidityJSONInterfaceTest.cpp +++ b/test/solidityJSONInterfaceTest.cpp @@ -23,6 +23,7 @@ #include #include #include +#include namespace dev { @@ -36,7 +37,19 @@ class InterfaceChecker public: void checkInterface(std::string const& _code, std::string const& _expectedInterfaceString) { - m_compilerStack.parse(_code); + try + { + m_compilerStack.parse(_code); + } + catch (const std::exception& e) + { + std::string const* extra = boost::get_error_info(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.getInterface(); Json::Value generatedInterface; m_reader.parse(generatedInterfaceString, generatedInterface); @@ -52,7 +65,7 @@ private: Json::Reader m_reader; }; -BOOST_FIXTURE_TEST_SUITE(solidityABIJSON, InterfaceChecker) +BOOST_FIXTURE_TEST_SUITE(SolidityABIJSON, InterfaceChecker) BOOST_AUTO_TEST_CASE(basic_test) { diff --git a/test/solidityNatspecJSON.cpp b/test/solidityNatspecJSON.cpp index 5918eec99..5a4649d2e 100644 --- a/test/solidityNatspecJSON.cpp +++ b/test/solidityNatspecJSON.cpp @@ -23,6 +23,7 @@ #include #include #include +#include namespace dev { @@ -36,7 +37,19 @@ class DocumentationChecker public: void checkNatspec(std::string const& _code, std::string const& _expectedDocumentationString) { - m_compilerStack.parse(_code); + try + { + m_compilerStack.parse(_code); + } + catch (const std::exception& e) + { + std::string const* extra = boost::get_error_info(e); + std::string msg = std::string("Parsing contract failed with: ") + + e.what() + std::string("\n"); + if (extra) + msg += *extra; + BOOST_FAIL(msg); + } auto generatedDocumentationString = m_compilerStack.getDocumentation(); Json::Value generatedDocumentation; m_reader.parse(generatedDocumentationString, generatedDocumentation); @@ -69,6 +82,67 @@ BOOST_AUTO_TEST_CASE(basic_test) checkNatspec(sourceCode, natspec); } +BOOST_AUTO_TEST_CASE(multiline_comment) +{ + char const* sourceCode = "contract test {\n" + " /// 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\":{ \"user\": \" Multiplies `a` by 7\n and then adds `b`\"}" + "}}"; + + checkNatspec(sourceCode, natspec); +} + +BOOST_AUTO_TEST_CASE(multiple_functions) +{ + char const* sourceCode = "contract test {\n" + " /// 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" + " /// Divides `input` by `div`\n" + " function divide(uint input, uint div) returns(uint d)\n" + " {\n" + " return input / div;\n" + " }\n" + " /// 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\":{ \"user\": \" Multiplies `a` by 7\n and then adds `b`\"}," + " \"divide\":{ \"user\": \" Divides `input` by `div`\"}," + " \"sub\":{ \"user\": \" Subtracts 3 from `input`\"}" + "}}"; + + checkNatspec(sourceCode, natspec); +} + +BOOST_AUTO_TEST_CASE(empty_contract) +{ + char const* sourceCode = "contract test {\n" + "}\n"; + + char const* natspec = "{\"methods\":{} }"; + + checkNatspec(sourceCode, natspec); +} + BOOST_AUTO_TEST_SUITE_END()