From 32dcc3f780c98b0dfb185218ae3f559700089bd1 Mon Sep 17 00:00:00 2001 From: lganzzzo Date: Fri, 1 Mar 2019 02:15:46 +0200 Subject: [PATCH] better detailed endpoint info support --- .../codegen/codegen_define_ApiController_.hpp | 8 +- src/oatpp/web/server/api/Endpoint.cpp | 3 +- src/oatpp/web/server/api/Endpoint.hpp | 2 +- test/CMakeLists.txt | 2 + test/oatpp/AllTestsMain.cpp | 2 + .../web/server/api/ApiControllerTest.cpp | 135 ++++++++++++++++++ .../web/server/api/ApiControllerTest.hpp | 42 ++++++ 7 files changed, 188 insertions(+), 6 deletions(-) create mode 100644 test/oatpp/web/server/api/ApiControllerTest.cpp create mode 100644 test/oatpp/web/server/api/ApiControllerTest.hpp diff --git a/src/oatpp/codegen/codegen_define_ApiController_.hpp b/src/oatpp/codegen/codegen_define_ApiController_.hpp index 4138474f..c67f23c8 100644 --- a/src/oatpp/codegen/codegen_define_ApiController_.hpp +++ b/src/oatpp/codegen/codegen_define_ApiController_.hpp @@ -96,10 +96,10 @@ OATPP_MACRO_API_CONTROLLER_HEADER_CHOOSER_EXP(TYPE, NAME, PARAM_LIST, OATPP_MACR // __INFO #define OATPP_MACRO_API_CONTROLLER_HEADER_INFO_0(TYPE, NAME, PARAM_LIST) \ -info->headers.add(#NAME).type = TYPE::Class::getType(); +info->headers.add(#NAME, TYPE::Class::getType()); #define OATPP_MACRO_API_CONTROLLER_HEADER_INFO_1(TYPE, NAME, PARAM_LIST) \ -info->headers.add(OATPP_MACRO_FIRSTARG PARAM_LIST).type = TYPE::Class::getType(); +info->headers.add(OATPP_MACRO_FIRSTARG PARAM_LIST, TYPE::Class::getType()); #define OATPP_MACRO_API_CONTROLLER_HEADER_INFO_CHOOSER(TYPE, NAME, PARAM_LIST, HAS_ARGS) \ OATPP_MACRO_API_CONTROLLER_HEADER_INFO_##HAS_ARGS (TYPE, NAME, PARAM_LIST) @@ -150,10 +150,10 @@ OATPP_MACRO_API_CONTROLLER_PATH_CHOOSER_EXP(TYPE, NAME, PARAM_LIST, OATPP_MACRO_ // __INFO #define OATPP_MACRO_API_CONTROLLER_PATH_INFO_0(TYPE, NAME, PARAM_LIST) \ -info->pathParams.add(#NAME).type = TYPE::Class::getType(); +info->pathParams.add(#NAME, TYPE::Class::getType()); #define OATPP_MACRO_API_CONTROLLER_PATH_INFO_1(TYPE, NAME, PARAM_LIST) \ -info->pathParams.add(OATPP_MACRO_FIRSTARG PARAM_LIST).type = TYPE::Class::getType(); +info->pathParams.add(OATPP_MACRO_FIRSTARG PARAM_LIST, TYPE::Class::getType()); #define OATPP_MACRO_API_CONTROLLER_PATH_INFO_CHOOSER(TYPE, NAME, PARAM_LIST, HAS_ARGS) \ OATPP_MACRO_API_CONTROLLER_PATH_INFO_##HAS_ARGS (TYPE, NAME, PARAM_LIST) diff --git a/src/oatpp/web/server/api/Endpoint.cpp b/src/oatpp/web/server/api/Endpoint.cpp index 2be811f0..5d86a586 100644 --- a/src/oatpp/web/server/api/Endpoint.cpp +++ b/src/oatpp/web/server/api/Endpoint.cpp @@ -43,10 +43,11 @@ const std::list& Endpoint::Info::Params::getOrder() const { return m_order; } -Endpoint::Info::Param& Endpoint::Info::Params::add(const oatpp::String& name) { +Endpoint::Info::Param& Endpoint::Info::Params::add(const oatpp::String& name, oatpp::data::mapping::type::Type* type) { m_order.push_back(name); Endpoint::Info::Param& param = operator [](name); param.name = name; + param.type = type; return param; } diff --git a/src/oatpp/web/server/api/Endpoint.hpp b/src/oatpp/web/server/api/Endpoint.hpp index e6f45563..f7d94a7a 100644 --- a/src/oatpp/web/server/api/Endpoint.hpp +++ b/src/oatpp/web/server/api/Endpoint.hpp @@ -87,7 +87,7 @@ public: * @param name * @return new or existing parameter */ - Param& add(const oatpp::String& name); + Param& add(const oatpp::String& name, oatpp::data::mapping::type::Type* type); /** * Get or add param by name diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt index b55fdf73..3cca0919 100644 --- a/test/CMakeLists.txt +++ b/test/CMakeLists.txt @@ -33,6 +33,8 @@ add_executable(oatppAllTests oatpp/parser/json/mapping/DTOMapperTest.hpp oatpp/parser/json/mapping/DeserializerTest.cpp oatpp/parser/json/mapping/DeserializerTest.hpp + oatpp/web/server/api/ApiControllerTest.cpp + oatpp/web/server/api/ApiControllerTest.hpp oatpp/web/FullAsyncTest.cpp oatpp/web/FullAsyncTest.hpp oatpp/web/FullTest.cpp diff --git a/test/oatpp/AllTestsMain.cpp b/test/oatpp/AllTestsMain.cpp index 14a819b0..9f31efc2 100644 --- a/test/oatpp/AllTestsMain.cpp +++ b/test/oatpp/AllTestsMain.cpp @@ -1,6 +1,7 @@ #include "oatpp/web/FullTest.hpp" #include "oatpp/web/FullAsyncTest.hpp" +#include "oatpp/web/server/api/ApiControllerTest.hpp" #include "oatpp/network/virtual_/PipeTest.hpp" #include "oatpp/network/virtual_/InterfaceTest.hpp" @@ -75,6 +76,7 @@ void runTests() { OATPP_RUN_TEST(oatpp::test::network::virtual_::PipeTest); OATPP_RUN_TEST(oatpp::test::network::virtual_::InterfaceTest); + OATPP_RUN_TEST(oatpp::test::web::server::api::ApiControllerTest); OATPP_RUN_TEST(oatpp::test::web::FullTest); OATPP_RUN_TEST(oatpp::test::web::FullAsyncTest); diff --git a/test/oatpp/web/server/api/ApiControllerTest.cpp b/test/oatpp/web/server/api/ApiControllerTest.cpp new file mode 100644 index 00000000..78101ad0 --- /dev/null +++ b/test/oatpp/web/server/api/ApiControllerTest.cpp @@ -0,0 +1,135 @@ +/*************************************************************************** + * + * Project _____ __ ____ _ _ + * ( _ ) /__\ (_ _)_| |_ _| |_ + * )(_)( /(__)\ )( (_ _)(_ _) + * (_____)(__)(__)(__) |_| |_| + * + * + * Copyright 2018-present, Leonid Stryzhevskyi + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + ***************************************************************************/ + +#include "ApiControllerTest.hpp" + +#include "oatpp/web/server/api/ApiController.hpp" +#include "oatpp/core/data/stream/ChunkedBuffer.hpp" +#include "oatpp/core/macro/codegen.hpp" + +namespace oatpp { namespace test { namespace web { namespace server { namespace api { + +namespace { + +class Controller : public oatpp::web::server::api::ApiController { +public: + Controller(const std::shared_ptr& objectMapper) + : oatpp::web::server::api::ApiController(objectMapper) + {} +public: + + static std::shared_ptr createShared(const std::shared_ptr& objectMapper){ + return std::make_shared(objectMapper); + } + +#include OATPP_CODEGEN_BEGIN(ApiController) + + ENDPOINT_INFO(root) { + info->summary = "root_summary"; + info->addResponse(Status::CODE_200, "text/plain"); + info->addResponse(Status::CODE_404, "text/plain"); + } + ENDPOINT("GET", "/", root) { + return createResponse(Status::CODE_200, "test1"); + } + + ENDPOINT_INFO(pathParams) { + info->pathParams["param1"].description = "this is param1"; + info->queryParams.add("q1", String::Class::getType()).description = "query param"; + info->headers.add("X-TEST-HEADER", String::Class::getType()).description = "TEST-HEADER-PARAM"; + } + ENDPOINT("GET", "path/{param1}/{param2}", pathParams, + PATH(String, param1), + PATH(String, param2)) { + return createResponse(Status::CODE_200, "test2"); + } + +#include OATPP_CODEGEN_END(ApiController) + +}; + +} + +// methods/fields with "Z__" prefix are for internal use only. +// Do not use these methods/fields for user-tests as naming can be changed + +void ApiControllerTest::onRun() { + + typedef oatpp::web::protocol::http::Status Status; + + Controller controller(nullptr); + + { + auto endpoint = controller.Z__ENDPOINT_root; + OATPP_ASSERT(endpoint); + OATPP_ASSERT(endpoint->info->summary == "root_summary"); + + auto r200 = endpoint->info->responses[Status::CODE_200]; + OATPP_ASSERT(r200.contentType == "text/plain"); + OATPP_ASSERT(r200.schema == oatpp::String::Class::getType()); + + auto r404 = endpoint->info->responses[Status::CODE_404]; + OATPP_ASSERT(r404.contentType == "text/plain"); + OATPP_ASSERT(r404.schema == oatpp::String::Class::getType()); + + auto response = controller.root(); + OATPP_ASSERT(response->getStatus().code == 200); + + auto stream = oatpp::data::stream::ChunkedBuffer::createShared(); + response->send(stream); + + OATPP_LOGD(TAG, "response=\n---\n%s\n---\n", stream->toString()->c_str()); + + } + + { + auto endpoint = controller.Z__ENDPOINT_pathParams; + OATPP_ASSERT(endpoint); + OATPP_ASSERT(!endpoint->info->summary); + + OATPP_ASSERT(endpoint->info->pathParams["param1"].name == "param1"); + OATPP_ASSERT(endpoint->info->pathParams["param1"].description == "this is param1"); + + OATPP_ASSERT(endpoint->info->pathParams["param2"].name == "param2"); + OATPP_ASSERT(!endpoint->info->pathParams["param2"].description); + + OATPP_ASSERT(endpoint->info->queryParams["q1"].name == "q1"); + OATPP_ASSERT(endpoint->info->queryParams["q1"].description == "query param"); + + OATPP_ASSERT(endpoint->info->headers["X-TEST-HEADER"].name == "X-TEST-HEADER"); + OATPP_ASSERT(endpoint->info->headers["X-TEST-HEADER"].description == "TEST-HEADER-PARAM"); + + auto response = controller.pathParams("p1", "p2"); + OATPP_ASSERT(response->getStatus().code == 200); + + auto stream = oatpp::data::stream::ChunkedBuffer::createShared(); + response->send(stream); + + OATPP_LOGD(TAG, "response=\n---\n%s\n---\n", stream->toString()->c_str()); + + } + +} + +}}}}} \ No newline at end of file diff --git a/test/oatpp/web/server/api/ApiControllerTest.hpp b/test/oatpp/web/server/api/ApiControllerTest.hpp new file mode 100644 index 00000000..0acc2af1 --- /dev/null +++ b/test/oatpp/web/server/api/ApiControllerTest.hpp @@ -0,0 +1,42 @@ +/*************************************************************************** + * + * Project _____ __ ____ _ _ + * ( _ ) /__\ (_ _)_| |_ _| |_ + * )(_)( /(__)\ )( (_ _)(_ _) + * (_____)(__)(__)(__) |_| |_| + * + * + * Copyright 2018-present, Leonid Stryzhevskyi + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + ***************************************************************************/ + +#ifndef oatpp_test_web_server_api_ApiControllerTest_hpp +#define oatpp_test_web_server_api_ApiControllerTest_hpp + +#include "oatpp-test/UnitTest.hpp" + +namespace oatpp { namespace test { namespace web { namespace server { namespace api { + +class ApiControllerTest : public UnitTest { +public: + + ApiControllerTest():UnitTest("TEST[web::server::api::ApiControllerTest]"){} + void onRun() override; + +}; + +}}}}} + +#endif /* oatpp_test_web_server_api_ApiControllerTest_hpp */