Skip to content
New issue

Have a question about this project? # for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “#”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? # to your account

[cpp-restsdk] Generate mockable APIs #595

Merged
merged 9 commits into from
Jul 24, 2018
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,7 @@ public class CppRestSdkClientCodegen extends AbstractCppCodegen {

public static final String DECLSPEC = "declspec";
public static final String DEFAULT_INCLUDE = "defaultInclude";
public static final String GENERATE_GMOCKS_FOR_APIS = "generateGMocksForApis";

protected String packageVersion = "1.0.0";
protected String declspec = "";
Expand Down Expand Up @@ -114,6 +115,9 @@ public CppRestSdkClientCodegen() {
addOption(DEFAULT_INCLUDE,
"The default include statement that should be placed in all headers for including things like the declspec (convention: #include \"Commons.h\" ",
this.defaultInclude);
addOption(GENERATE_GMOCKS_FOR_APIS,
"Generate Google Mock classes for APIs.",
null);

supportingFiles.add(new SupportingFile("modelbase-header.mustache", "", "ModelBase.h"));
supportingFiles.add(new SupportingFile("modelbase-source.mustache", "", "ModelBase.cpp"));
Expand Down Expand Up @@ -176,6 +180,10 @@ public void processOpts() {
defaultInclude = additionalProperties.get(DEFAULT_INCLUDE).toString();
}

if (convertPropertyToBoolean(GENERATE_GMOCKS_FOR_APIS)) {
apiTemplateFiles.put("api-gmock.mustache", "GMock.h");
}

additionalProperties.put("modelNamespaceDeclarations", modelPackage.split("\\."));
additionalProperties.put("modelNamespace", modelPackage.replaceAll("\\.", "::"));
additionalProperties.put("modelHeaderGuardPrefix", modelPackage.replaceAll("\\.", "_").toUpperCase());
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
{{>licenseInfo}}
{{#operations}}
#ifndef {{apiHeaderGuardPrefix}}_{{classname}}GMock_H_
#define {{apiHeaderGuardPrefix}}_{{classname}}GMock_H_

#include <gmock/gmock.h>

#include "{{classname}}.h"

{{#apiNamespaceDeclarations}}
namespace {{this}} {
{{/apiNamespaceDeclarations}}

using namespace {{modelNamespace}};


class {{declspec}} {{classname}}Mock : public I{{classname}}
{
public:
{{#operation}}
MOCK_METHOD{{allParams.size}}( {{operationId}}, pplx::task<{{#returnType}}{{{returnType}}}{{/returnType}}{{^returnType}}void{{/returnType}}> (
{{#allParams}}
{{^required}}boost::optional<{{/required}}{{#isFile}}std::shared_ptr<{{/isFile}}{{{dataType}}}{{#isFile}}>{{/isFile}}{{^required}}>{{/required}} {{paramName}}{{#hasMore}},{{/hasMore}}
{{/allParams}}
) );
{{/operation}}
};

{{#apiNamespaceDeclarations}}
}
{{/apiNamespaceDeclarations}}

#endif /* {{apiHeaderGuardPrefix}}_{{classname}}GMock_H_ */

{{/operations}}
Original file line number Diff line number Diff line change
Expand Up @@ -22,11 +22,24 @@ namespace {{this}} {

using namespace {{modelNamespace}};

class {{declspec}} {{classname}}
class {{declspec}} I{{classname}}
Copy link
Contributor

@etherealjoy etherealjoy Jul 19, 2018

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this part should be encapsulated with the new mustache variable, so that current users are not impacted

{
public:
virtual ~I{{classname}}() = default;
{{#operation}}
virtual pplx::task<{{#returnType}}{{{returnType}}}{{/returnType}}{{^returnType}}void{{/returnType}}> {{operationId}}(
{{#allParams}}
{{^required}}boost::optional<{{/required}}{{#isFile}}std::shared_ptr<{{/isFile}}{{{dataType}}}{{#isFile}}>{{/isFile}}{{^required}}>{{/required}} {{paramName}}{{#hasMore}},{{/hasMore}}
{{/allParams}}
) = 0;
{{/operation}}
};

class {{declspec}} {{classname}} : public I{{classname}}
{
public:
{{classname}}( std::shared_ptr<ApiClient> apiClient );
virtual ~{{classname}}();
~{{classname}}() override;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Here as well

{{#operation}}
/// <summary>
/// {{summary}}
Expand All @@ -41,7 +54,7 @@ public:
{{#allParams}}
{{^required}}boost::optional<{{/required}}{{#isFile}}std::shared_ptr<{{/isFile}}{{{dataType}}}{{#isFile}}>{{/isFile}}{{^required}}>{{/required}} {{paramName}}{{#hasMore}},{{/hasMore}}
{{/allParams}}
);
) override;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

And here.

{{/operation}}

protected:
Expand Down
55 changes: 45 additions & 10 deletions samples/client/petstore/cpp-restsdk/api/PetApi.h
Original file line number Diff line number Diff line change
Expand Up @@ -35,11 +35,46 @@ namespace api {

using namespace org::openapitools::client::model;

class PetApi
class IPetApi
{
public:
virtual ~IPetApi() = default;
virtual pplx::task<void> addPet(
std::shared_ptr<Pet> pet
) = 0;
virtual pplx::task<void> deletePet(
int64_t petId,
boost::optional<utility::string_t> apiKey
) = 0;
virtual pplx::task<std::vector<std::shared_ptr<Pet>>> findPetsByStatus(
std::vector<utility::string_t> status
) = 0;
virtual pplx::task<std::vector<std::shared_ptr<Pet>>> findPetsByTags(
std::vector<utility::string_t> tags
) = 0;
virtual pplx::task<std::shared_ptr<Pet>> getPetById(
int64_t petId
) = 0;
virtual pplx::task<void> updatePet(
std::shared_ptr<Pet> pet
) = 0;
virtual pplx::task<void> updatePetWithForm(
int64_t petId,
boost::optional<utility::string_t> name,
boost::optional<utility::string_t> status
) = 0;
virtual pplx::task<std::shared_ptr<ApiResponse>> uploadFile(
int64_t petId,
boost::optional<utility::string_t> additionalMetadata,
boost::optional<HttpContent> file
) = 0;
};

class PetApi : public IPetApi
{
public:
PetApi( std::shared_ptr<ApiClient> apiClient );
virtual ~PetApi();
~PetApi() override;
/// <summary>
/// Add a new pet to the store
/// </summary>
Expand All @@ -49,7 +84,7 @@ class PetApi
/// <param name="pet">Pet object that needs to be added to the store</param>
pplx::task<void> addPet(
std::shared_ptr<Pet> pet
);
) override;
/// <summary>
/// Deletes a pet
/// </summary>
Expand All @@ -61,7 +96,7 @@ class PetApi
pplx::task<void> deletePet(
int64_t petId,
boost::optional<utility::string_t> apiKey
);
) override;
/// <summary>
/// Finds Pets by status
/// </summary>
Expand All @@ -71,7 +106,7 @@ class PetApi
/// <param name="status">Status values that need to be considered for filter</param>
pplx::task<std::vector<std::shared_ptr<Pet>>> findPetsByStatus(
std::vector<utility::string_t> status
);
) override;
/// <summary>
/// Finds Pets by tags
/// </summary>
Expand All @@ -81,7 +116,7 @@ class PetApi
/// <param name="tags">Tags to filter by</param>
pplx::task<std::vector<std::shared_ptr<Pet>>> findPetsByTags(
std::vector<utility::string_t> tags
);
) override;
/// <summary>
/// Find pet by ID
/// </summary>
Expand All @@ -91,7 +126,7 @@ class PetApi
/// <param name="petId">ID of pet to return</param>
pplx::task<std::shared_ptr<Pet>> getPetById(
int64_t petId
);
) override;
/// <summary>
/// Update an existing pet
/// </summary>
Expand All @@ -101,7 +136,7 @@ class PetApi
/// <param name="pet">Pet object that needs to be added to the store</param>
pplx::task<void> updatePet(
std::shared_ptr<Pet> pet
);
) override;
/// <summary>
/// Updates a pet in the store with form data
/// </summary>
Expand All @@ -115,7 +150,7 @@ class PetApi
int64_t petId,
boost::optional<utility::string_t> name,
boost::optional<utility::string_t> status
);
) override;
/// <summary>
/// uploads an image
/// </summary>
Expand All @@ -129,7 +164,7 @@ class PetApi
int64_t petId,
boost::optional<utility::string_t> additionalMetadata,
boost::optional<std::shared_ptr<HttpContent>> file
);
) override;

protected:
std::shared_ptr<ApiClient> m_ApiClient;
Expand Down
29 changes: 23 additions & 6 deletions samples/client/petstore/cpp-restsdk/api/StoreApi.h
Original file line number Diff line number Diff line change
Expand Up @@ -34,11 +34,28 @@ namespace api {

using namespace org::openapitools::client::model;

class StoreApi
class IStoreApi
{
public:
virtual ~IStoreApi() = default;
virtual pplx::task<void> deleteOrder(
utility::string_t orderId
) = 0;
virtual pplx::task<std::map<utility::string_t, int32_t>> getInventory(
) = 0;
virtual pplx::task<std::shared_ptr<Order>> getOrderById(
int64_t orderId
) = 0;
virtual pplx::task<std::shared_ptr<Order>> placeOrder(
std::shared_ptr<Order> order
) = 0;
};

class StoreApi : public IStoreApi
{
public:
StoreApi( std::shared_ptr<ApiClient> apiClient );
virtual ~StoreApi();
~StoreApi() override;
/// <summary>
/// Delete purchase order by ID
/// </summary>
Expand All @@ -48,15 +65,15 @@ class StoreApi
/// <param name="orderId">ID of the order that needs to be deleted</param>
pplx::task<void> deleteOrder(
utility::string_t orderId
);
) override;
/// <summary>
/// Returns pet inventories by status
/// </summary>
/// <remarks>
/// Returns a map of status codes to quantities
/// </remarks>
pplx::task<std::map<utility::string_t, int32_t>> getInventory(
);
) override;
/// <summary>
/// Find purchase order by ID
/// </summary>
Expand All @@ -66,7 +83,7 @@ class StoreApi
/// <param name="orderId">ID of pet that needs to be fetched</param>
pplx::task<std::shared_ptr<Order>> getOrderById(
int64_t orderId
);
) override;
/// <summary>
/// Place an order for a pet
/// </summary>
Expand All @@ -76,7 +93,7 @@ class StoreApi
/// <param name="order">order placed for purchasing the pet</param>
pplx::task<std::shared_ptr<Order>> placeOrder(
std::shared_ptr<Order> order
);
) override;

protected:
std::shared_ptr<ApiClient> m_ApiClient;
Expand Down
Loading