Skip to content

Commit

Permalink
Support for building with code coverage (also used internally for CDa…
Browse files Browse the repository at this point in the history
…sh reporting)

Removed some compilation warnings (unused paramters)
Added Service test
  • Loading branch information
Rodrigo Fernandes committed Oct 3, 2013
1 parent 02018fb commit 29a7bd3
Show file tree
Hide file tree
Showing 10 changed files with 195 additions and 33 deletions.
11 changes: 11 additions & 0 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -90,4 +90,15 @@ add_subdirectory(examples)

enable_testing()
include(CTest)

option(CodeCoverage "Build support for code coverage (requires -DCMAKE_BUILD_TYPE=Debug)" OFF)

if (CodeCoverage)
message (STATUS "Building with code coverage support")
set (CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} -g -O0 -Wall -W -Wshadow -Wunused-variable -Wunused-parameter -Wunused-function -Wunused -Wno-system-headers -Wno-deprecated -Woverloaded-virtual -Wwrite-strings -fprofile-arcs -ftest-coverage")
set (CMAKE_C_FLAGS_DEBUG "${CMAKE_C_FLAGS_DEBUG} -g -O0 -Wall -W -fprofile-arcs -ftest-coverage")
set (CMAKE_SHARED_LINKER_FLAGS_DEBUG "${CMAKE_SHARED_LINKER_FLAGS_DEBUG} -fprofile-arcs -ftest-coverage")
set (CMAKE_EXE_LINKER_FLAGS_DEBUG "${CMAKE_EXE_LINKER_FLAGS_DEBUG} -fprofile-arcs -ftest-coverage")
endif()

add_subdirectory(tests)
35 changes: 35 additions & 0 deletions examples/include/Instantiation.hh
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
#ifndef _CALCULATOR_HH_
#define _CALCULATOR_HH_
#include <answer/Operation.hh>
#include <string>
#include <set>

namespace WebServices{

///Define request and response types
struct Data{
double result;

template<class Archive>
void serialize(Archive &ar, const unsigned int /*version*/){
ar & BOOST_SERIALIZATION_NVP(result);
}
};

///Complex type service testing
class Instantiation: public answer::instantiation::Singleton{
public:
Data calculator(const Data &request);
};

///Complex type service testing
class Instantiation{
public:
Data calculator(const Data &request);
};

ANSWER_REGISTER_OPERATION(MyService::calculator);

}

#endif // _CALCULATOR_HH_
32 changes: 32 additions & 0 deletions examples/src/Instantiation.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
#include ".hh"

using namespace std;
using namespace answer;

namespace WebServices{

CalculatorResponse MyService::calculator(const CalculatorRequest &request){
CalculatorResponse response;
switch(request.operation){
case 'x':
case '*':
response.result = request.operand1 * request.operand2;
break;
case '-':
response.result = request.operand1 - request.operand2;
break;
case 'd':
case '/':
response.result = request.operand1 / request.operand2;
break;
case '+':
response.result = request.operand1 + request.operand2;
break;
default:
throw WebMethodInvalidInput("Invalid operation requested");
}

return response;
}

}
2 changes: 1 addition & 1 deletion include/answer/Codec.hh
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ namespace answer{
}

template<typename T>
bool ResponseWrapper( std::ostream& out, const std::string& response, const std::string& mimeType, const answer::WebMethodException*)
bool ResponseWrapper( std::ostream& out, const std::string& response, const std::string& /*mimeType*/, const answer::WebMethodException*)
{
out << response;
return true;
Expand Down
2 changes: 1 addition & 1 deletion include/answer/Operation.hh
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ public:
Operation(const std::string& name):_name(name){}
virtual ~Operation() {};
//The invocation wrapper
virtual Response invoke(const std::string&, const std::string & ="")=0;
virtual Response invoke(const std::string& params, const std::string & prefix="")=0;
};

template <typename RequestT>
Expand Down
3 changes: 3 additions & 0 deletions tests/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
add_subdirectory(serialization)
add_subdirectory(service)
add_subdirectory(module)
25 changes: 0 additions & 25 deletions tests/registration/RegistrationTest.cpp

This file was deleted.

2 changes: 0 additions & 2 deletions tests/serialization/SerializationTest.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -24,8 +24,6 @@ struct testInput{
}
};



BOOST_AUTO_TEST_CASE( serialization )
{
testInput testIntSet1;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,17 +1,17 @@
find_package(Boost COMPONENTS unit_test_framework REQUIRED QUIET)

add_executable(registrationTest
RegistrationTest.cpp
add_executable(serviceTest
ServiceTest.cpp
)

include_directories(
${Boost_INCLUDE_DIRS}
)

target_link_libraries(registrationTest
target_link_libraries(serviceTest
${Boost_LIBRARIES}
answer
)

add_test(registration registrationTest)
add_test(service serviceTest)

108 changes: 108 additions & 0 deletions tests/service/ServiceTest.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,108 @@
#define BOOST_TEST_MODULE RegistrationTest
#include <boost/test/included/unit_test.hpp>

//Normally this is defined in the build file, it's usually the project name
#define ANSWER_SERVICE_NAME "RegistrationTest"

#include "answer/Operation.hh"
#include <boost/algorithm/string.hpp>

using namespace std;

class Operation{
public:
int test(string X){
return X.size();
}
};

ANSWER_REGISTER_OPERATION(Operation::test);


class TestContext: public
answer::Context,
answer::TransportInfo,
answer::OperationInfo{

string _service;
string _operation;
string _accept;
list<string> _accepts;

public:
TestContext(const string &serviceName, const string &operationName, const string& acceptsType):
_service(serviceName), _operation(operationName), _accepts({acceptsType}){
}

//Context
virtual answer::CookieJar& cookieJar(){
throw std::runtime_error("CookieJar not implemented");
}
virtual answer::Environment& environment(){
throw std::runtime_error("Environment not implemented");
}
virtual answer::OperationInfo& operationInfo(){
return *this;
}
virtual answer::ProviderStore& providerStore(){
throw std::runtime_error("ProviderStore not implemented");
}
virtual answer::TransportInfo& transportInfo(){
return *this;
}

//TransportInfo
virtual const list<string>& accepts() const{
return _accepts;
}
virtual void addHeader ( const string& /*key*/, const string& /*value*/ = "", bool /*replace*/ = true ){
throw std::runtime_error("addHeader not implemented");
}
virtual const string& redirect() const{
throw std::runtime_error("redirect not implemented");
}
virtual const string& redirect ( const string& /*uri*/ ){
throw std::runtime_error("redirect (set) not implemented");
}
virtual bool redirectSet() const{
return false;
}

//OperationInfo
virtual const string& operation() const{
return _operation;
}
virtual const string& service() const{
return _service;
}
virtual const string& url() const{
throw std::runtime_error("url not implemented");
}

};


BOOST_AUTO_TEST_CASE( registration )
{
list<string> operations = answer::OperationStore::Instance().operationList();
BOOST_CHECK(operations.front() == string("RegistrationTest/test"));
}

BOOST_AUTO_TEST_CASE( request_response ){
TestContext context("RegistrationTest", "test", "application/xml");
answer::Operation &operation = answer::OperationStore::Instance().operation("RegistrationTest", "test");
answer::Response response = operation.invoke("<test>foobar</test>");
string body = response.body();
boost::trim(body);
BOOST_CHECK(body == "<test>6</test>");
}

BOOST_AUTO_TEST_CASE( request_response_codec ){
TestContext context("RegistrationTest", "test", "application/json");
answer::Operation &operation = answer::OperationStore::Instance().operation("RegistrationTest", "test");
answer::Response response = operation.invoke("<test>foobar</test>");
string body = response.body();
boost::trim(body);
BOOST_CHECK(body == "\"6\"");
}

0 comments on commit 29a7bd3

Please sign in to comment.