tests for models for C-libcurl generator (#5699)

* First try to generate unit tests for the models of the C-libcurl client. Models into models are not supported yet.

* Added unit tests for the modules of the C-libcurl client to the git repository.

* Support for objects having other objects as properties, for the C-libcurl client generator

* Proper formatting of generated code
This commit is contained in:
Michele Albano 2020-04-05 19:42:50 +02:00 committed by GitHub
parent 166aae6fec
commit e9c1346386
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
15 changed files with 580 additions and 6 deletions

View File

@ -87,7 +87,7 @@ public class CLibcurlClientCodegen extends DefaultCodegen implements CodegenConf
embeddedTemplateDir = templateDir = "C-libcurl";
// TODO add auto-generated test files
//modelTestTemplateFiles.put("model_test.mustache", ".c");
modelTestTemplateFiles.put("model_test.mustache", ".c");
//apiTestTemplateFiles.put("api_test.mustache", ".c");
// default HIDE_GENERATION_TIMESTAMP to true
@ -321,6 +321,104 @@ public class CLibcurlClientCodegen extends DefaultCodegen implements CodegenConf
return null;
}
@Override
public String toExampleValue(Schema schema) {
String example = super.toExampleValue(schema);
if (ModelUtils.isNullType(schema) && null != example) {
// The 'null' type is allowed in OAS 3.1 and above. It is not supported by OAS 3.0.x,
// though this tooling supports it.
return "NULL";
}
// correct "'"s into "'"s after toString()
if (ModelUtils.isStringSchema(schema) && schema.getDefault() != null) {
example = (String) schema.getDefault();
}
if (StringUtils.isNotBlank(example) && !"null".equals(example)) {
if (ModelUtils.isStringSchema(schema)) {
example = "\"" + example + "\"";
}
return example;
}
if (schema.getEnum() != null && !schema.getEnum().isEmpty()) {
// Enum case:
example = schema.getEnum().get(0).toString();
/* if (ModelUtils.isStringSchema(schema)) {
example = "'" + escapeText(example) + "'";
}*/
if (null == example)
LOGGER.warn("Empty enum. Cannot built an example!");
return example;
} else if (null != schema.get$ref()) {
// $ref case:
Map<String, Schema> allDefinitions = ModelUtils.getSchemas(this.openAPI);
String ref = ModelUtils.getSimpleRef(schema.get$ref());
if (allDefinitions != null) {
Schema refSchema = allDefinitions.get(ref);
if (null == refSchema) {
return "None";
} else {
String refTitle = refSchema.getTitle();
if (StringUtils.isBlank(refTitle) || "null".equals(refTitle)) {
refSchema.setTitle(ref);
}
return toExampleValue(refSchema);
}
} else {
LOGGER.warn("allDefinitions not defined in toExampleValue!\n");
}
}
if (ModelUtils.isDateSchema(schema)) {
example = "\"2013-10-20\"";
return example;
} else if (ModelUtils.isDateTimeSchema(schema)) {
example = "\"2013-10-20T19:20:30+01:00\"";
return example;
} else if (ModelUtils.isBinarySchema(schema)) {
example = "bytes(b'blah')";
return example;
} else if (ModelUtils.isByteArraySchema(schema)) {
example = "YQ==";
} else if (ModelUtils.isStringSchema(schema)) {
// a BigDecimal:
if ("Number".equalsIgnoreCase(schema.getFormat())) {return "1";}
if (StringUtils.isNotBlank(schema.getPattern())) return "'a'"; // I cheat here, since it would be too complicated to generate a string from a regexp
int len = 0;
if (null != schema.getMinLength()) len = schema.getMinLength().intValue();
if (len < 1) len = 1;
example = "";
for (int i=0;i<len;i++) example += i;
} else if (ModelUtils.isIntegerSchema(schema)) {
if (schema.getMinimum() != null)
example = schema.getMinimum().toString();
else
example = "56";
} else if (ModelUtils.isNumberSchema(schema)) {
if (schema.getMinimum() != null)
example = schema.getMinimum().toString();
else
example = "1.337";
} else if (ModelUtils.isBooleanSchema(schema)) {
example = "1";
} else if (ModelUtils.isArraySchema(schema)) {
example = "list_create()";
} else if (ModelUtils.isMapSchema(schema)) {
example = "list_create()";
} else if (ModelUtils.isObjectSchema(schema)) {
return null; // models are managed at moustache level
} else {
LOGGER.warn("Type " + schema.getType() + " not handled properly in toExampleValue");
}
if (ModelUtils.isStringSchema(schema)) {
example = "\"" + escapeText(example) + "\"";
}
return example;
}
@Override
public String getSchemaType(Schema schema) {
String openAPIType = super.getSchemaType(schema);
@ -431,7 +529,7 @@ public class CLibcurlClientCodegen extends DefaultCodegen implements CodegenConf
@Override
public String toModelTestFilename(String name) {
return ("test_" + toModelFilename(name)).replaceAll("_", "-");
return ("test_" + toModelFilename(name));
}
@Override

View File

@ -11,6 +11,9 @@
#include "../external/cJSON.h"
#include "../include/list.h"
#include "../include/keyValuePair.h"
typedef struct {{classname}}_t {{classname}}_t;
{{#imports}}
#include "{{{.}}}.h"
{{/imports}}

View File

@ -1,11 +1,74 @@
{{#models}}
{{#model}}
#ifndef {{classFilename}}_TEST
#define {{classFilename}}_TEST
// the following is to include only the main from the first c file
#ifndef TEST_MAIN
#define TEST_MAIN
#define {{classFilename}}_MAIN
#endif // TEST_MAIN
#include <stdlib.h>
#include <string.h>
#include <stdio.h>
#include "cJSON.h"
{{#imports}}{{{import}}}
{{/imports}}
#include <stdbool.h>
#include "../external/cJSON.h"
#include "../model/{{classFilename}}.h"
{{classname}}_t* instantiate_{{classname}}(int include_optional);
{{#vars}}{{#isModel}}{{#isEnum}}
// it is enum. Work in Progress
{{/isEnum}}{{^isEnum}}#include "test_{{{dataType}}}.c"
{{/isEnum}}{{/isModel}}{{/vars}}
{{classname}}_t* instantiate_{{classname}}(int include_optional) {
{{classname}}_t* {{classname}} = NULL;
if (include_optional) {
{{classname}} = {{classname}}_create(
{{#vars}} {{#isEnum}}{{^isContainer}}{{#example}}{{projectName}}_{{classVarName}}_{{enumName}}_{{{.}}}{{/example}}{{/isContainer}}{{#isContainer}}{{#example}}{{{.}}}{{/example}}{{/isContainer}}{{/isEnum}}{{^isEnum}}{{#example}}{{{.}}}{{/example}}{{/isEnum}}{{^example}}{{#isModel}}{{#isEnum}}// enum {{datatypeWithEnum}}_e Work in Progress
{{/isEnum}}{{^isEnum}} // false, not to have infinite recursion
instantiate_{{{dataType}}}(0){{/isEnum}}{{/isModel}}{{^isModel}}0{{/isModel}}{{/example}}{{#hasMore}},{{/hasMore}}
{{/vars}}
);
} else {
{{classname}} = {{classname}}_create(
{{#vars}} {{#isEnum}}{{^isContainer}}{{#example}}{{projectName}}_{{classVarName}}_{{enumName}}_{{{.}}}{{/example}}{{/isContainer}}{{#isContainer}}{{#example}}{{{.}}}{{/example}}{{/isContainer}}{{/isEnum}}{{^isEnum}}{{#example}}{{{.}}}{{/example}}{{/isEnum}}{{^example}}{{#isModel}}{{#isEnum}}// enum {{datatypeWithEnum}}_e Work in Progress
{{/isEnum}}{{^isEnum}}NULL{{/isEnum}}{{/isModel}}{{^isModel}}0{{/isModel}}{{/example}}{{#hasMore}},{{/hasMore}}
{{/vars}}
);
}
return {{classname}};
}
#ifdef {{classFilename}}_MAIN
void test_{{classname}}(int include_optional) {
{{classname}}_t* {{classname}}_1 = instantiate_{{classname}}(include_optional);
cJSON* json{{classname}}_1 = {{classname}}_convertToJSON({{classname}}_1);
printf("{{classname}} :\n%s\n", cJSON_Print(json{{classname}}_1));
{{classname}}_t* {{classname}}_2 = {{classname}}_parseFromJSON(json{{classname}}_1);
cJSON* json{{classname}}_2 = {{classname}}_convertToJSON({{classname}}_2);
printf("repeating {{classname}}:\n%s\n", cJSON_Print(json{{classname}}_2));
}
int main() {
printf("Hello world \n");
{{#models}}
{{#model}}
test_{{classname}}(1);
test_{{classname}}(0);
{{/model}}
{{/models}}
printf("Hello world \n");
return 0;
}
#endif // {{classFilename}}_MAIN
#endif // {{classFilename}}_TEST
{{/model}}
{{/models}}

View File

@ -12,6 +12,9 @@
#include "../include/list.h"
#include "../include/keyValuePair.h"
typedef struct api_response_t api_response_t;
typedef struct api_response_t {

View File

@ -12,6 +12,9 @@
#include "../include/list.h"
#include "../include/keyValuePair.h"
typedef struct category_t category_t;
typedef struct category_t {

View File

@ -12,6 +12,9 @@
#include "../include/list.h"
#include "../include/keyValuePair.h"
typedef struct order_t order_t;
// Enum STATUS for order
typedef enum { openapi_petstore_order_STATUS_NULL = 0, openapi_petstore_order_STATUS_placed, openapi_petstore_order_STATUS_approved, openapi_petstore_order_STATUS_delivered } openapi_petstore_order_STATUS_e;

View File

@ -11,6 +11,9 @@
#include "../external/cJSON.h"
#include "../include/list.h"
#include "../include/keyValuePair.h"
typedef struct pet_t pet_t;
#include "category.h"
#include "tag.h"

View File

@ -12,6 +12,9 @@
#include "../include/list.h"
#include "../include/keyValuePair.h"
typedef struct tag_t tag_t;
typedef struct tag_t {

View File

@ -12,6 +12,9 @@
#include "../include/list.h"
#include "../include/keyValuePair.h"
typedef struct user_t user_t;
typedef struct user_t {

View File

@ -0,0 +1,62 @@
#ifndef api_response_TEST
#define api_response_TEST
// the following is to include only the main from the first c file
#ifndef TEST_MAIN
#define TEST_MAIN
#define api_response_MAIN
#endif // TEST_MAIN
#include <stdlib.h>
#include <string.h>
#include <stdio.h>
#include <stdbool.h>
#include "../external/cJSON.h"
#include "../model/api_response.h"
api_response_t* instantiate_api_response(int include_optional);
api_response_t* instantiate_api_response(int include_optional) {
api_response_t* api_response = NULL;
if (include_optional) {
api_response = api_response_create(
56,
"0",
"0"
);
} else {
api_response = api_response_create(
56,
"0",
"0"
);
}
return api_response;
}
#ifdef api_response_MAIN
void test_api_response(int include_optional) {
api_response_t* api_response_1 = instantiate_api_response(include_optional);
cJSON* jsonapi_response_1 = api_response_convertToJSON(api_response_1);
printf("api_response :\n%s\n", cJSON_Print(jsonapi_response_1));
api_response_t* api_response_2 = api_response_parseFromJSON(jsonapi_response_1);
cJSON* jsonapi_response_2 = api_response_convertToJSON(api_response_2);
printf("repeating api_response:\n%s\n", cJSON_Print(jsonapi_response_2));
}
int main() {
test_api_response(1);
test_api_response(0);
printf("Hello world \n");
return 0;
}
#endif // api_response_MAIN
#endif // api_response_TEST

View File

@ -0,0 +1,60 @@
#ifndef category_TEST
#define category_TEST
// the following is to include only the main from the first c file
#ifndef TEST_MAIN
#define TEST_MAIN
#define category_MAIN
#endif // TEST_MAIN
#include <stdlib.h>
#include <string.h>
#include <stdio.h>
#include <stdbool.h>
#include "../external/cJSON.h"
#include "../model/category.h"
category_t* instantiate_category(int include_optional);
category_t* instantiate_category(int include_optional) {
category_t* category = NULL;
if (include_optional) {
category = category_create(
56,
"0"
);
} else {
category = category_create(
56,
"0"
);
}
return category;
}
#ifdef category_MAIN
void test_category(int include_optional) {
category_t* category_1 = instantiate_category(include_optional);
cJSON* jsoncategory_1 = category_convertToJSON(category_1);
printf("category :\n%s\n", cJSON_Print(jsoncategory_1));
category_t* category_2 = category_parseFromJSON(jsoncategory_1);
cJSON* jsoncategory_2 = category_convertToJSON(category_2);
printf("repeating category:\n%s\n", cJSON_Print(jsoncategory_2));
}
int main() {
test_category(1);
test_category(0);
printf("Hello world \n");
return 0;
}
#endif // category_MAIN
#endif // category_TEST

View File

@ -0,0 +1,68 @@
#ifndef order_TEST
#define order_TEST
// the following is to include only the main from the first c file
#ifndef TEST_MAIN
#define TEST_MAIN
#define order_MAIN
#endif // TEST_MAIN
#include <stdlib.h>
#include <string.h>
#include <stdio.h>
#include <stdbool.h>
#include "../external/cJSON.h"
#include "../model/order.h"
order_t* instantiate_order(int include_optional);
order_t* instantiate_order(int include_optional) {
order_t* order = NULL;
if (include_optional) {
order = order_create(
56,
56,
56,
"2013-10-20T19:20:30+01:00",
openapi_petstore_order_STATUS_placed,
1
);
} else {
order = order_create(
56,
56,
56,
"2013-10-20T19:20:30+01:00",
openapi_petstore_order_STATUS_placed,
1
);
}
return order;
}
#ifdef order_MAIN
void test_order(int include_optional) {
order_t* order_1 = instantiate_order(include_optional);
cJSON* jsonorder_1 = order_convertToJSON(order_1);
printf("order :\n%s\n", cJSON_Print(jsonorder_1));
order_t* order_2 = order_parseFromJSON(jsonorder_1);
cJSON* jsonorder_2 = order_convertToJSON(order_2);
printf("repeating order:\n%s\n", cJSON_Print(jsonorder_2));
}
int main() {
test_order(1);
test_order(0);
printf("Hello world \n");
return 0;
}
#endif // order_MAIN
#endif // order_TEST

View File

@ -0,0 +1,70 @@
#ifndef pet_TEST
#define pet_TEST
// the following is to include only the main from the first c file
#ifndef TEST_MAIN
#define TEST_MAIN
#define pet_MAIN
#endif // TEST_MAIN
#include <stdlib.h>
#include <string.h>
#include <stdio.h>
#include <stdbool.h>
#include "../external/cJSON.h"
#include "../model/pet.h"
pet_t* instantiate_pet(int include_optional);
#include "test_category.c"
pet_t* instantiate_pet(int include_optional) {
pet_t* pet = NULL;
if (include_optional) {
pet = pet_create(
56,
// false, not to have infinite recursion
instantiate_category(0),
"doggie",
list_create(),
list_create(),
openapi_petstore_pet_STATUS_available
);
} else {
pet = pet_create(
56,
NULL,
"doggie",
list_create(),
list_create(),
openapi_petstore_pet_STATUS_available
);
}
return pet;
}
#ifdef pet_MAIN
void test_pet(int include_optional) {
pet_t* pet_1 = instantiate_pet(include_optional);
cJSON* jsonpet_1 = pet_convertToJSON(pet_1);
printf("pet :\n%s\n", cJSON_Print(jsonpet_1));
pet_t* pet_2 = pet_parseFromJSON(jsonpet_1);
cJSON* jsonpet_2 = pet_convertToJSON(pet_2);
printf("repeating pet:\n%s\n", cJSON_Print(jsonpet_2));
}
int main() {
test_pet(1);
test_pet(0);
printf("Hello world \n");
return 0;
}
#endif // pet_MAIN
#endif // pet_TEST

View File

@ -0,0 +1,60 @@
#ifndef tag_TEST
#define tag_TEST
// the following is to include only the main from the first c file
#ifndef TEST_MAIN
#define TEST_MAIN
#define tag_MAIN
#endif // TEST_MAIN
#include <stdlib.h>
#include <string.h>
#include <stdio.h>
#include <stdbool.h>
#include "../external/cJSON.h"
#include "../model/tag.h"
tag_t* instantiate_tag(int include_optional);
tag_t* instantiate_tag(int include_optional) {
tag_t* tag = NULL;
if (include_optional) {
tag = tag_create(
56,
"0"
);
} else {
tag = tag_create(
56,
"0"
);
}
return tag;
}
#ifdef tag_MAIN
void test_tag(int include_optional) {
tag_t* tag_1 = instantiate_tag(include_optional);
cJSON* jsontag_1 = tag_convertToJSON(tag_1);
printf("tag :\n%s\n", cJSON_Print(jsontag_1));
tag_t* tag_2 = tag_parseFromJSON(jsontag_1);
cJSON* jsontag_2 = tag_convertToJSON(tag_2);
printf("repeating tag:\n%s\n", cJSON_Print(jsontag_2));
}
int main() {
test_tag(1);
test_tag(0);
printf("Hello world \n");
return 0;
}
#endif // tag_MAIN
#endif // tag_TEST

View File

@ -0,0 +1,72 @@
#ifndef user_TEST
#define user_TEST
// the following is to include only the main from the first c file
#ifndef TEST_MAIN
#define TEST_MAIN
#define user_MAIN
#endif // TEST_MAIN
#include <stdlib.h>
#include <string.h>
#include <stdio.h>
#include <stdbool.h>
#include "../external/cJSON.h"
#include "../model/user.h"
user_t* instantiate_user(int include_optional);
user_t* instantiate_user(int include_optional) {
user_t* user = NULL;
if (include_optional) {
user = user_create(
56,
"0",
"0",
"0",
"0",
"0",
"0",
56
);
} else {
user = user_create(
56,
"0",
"0",
"0",
"0",
"0",
"0",
56
);
}
return user;
}
#ifdef user_MAIN
void test_user(int include_optional) {
user_t* user_1 = instantiate_user(include_optional);
cJSON* jsonuser_1 = user_convertToJSON(user_1);
printf("user :\n%s\n", cJSON_Print(jsonuser_1));
user_t* user_2 = user_parseFromJSON(jsonuser_1);
cJSON* jsonuser_2 = user_convertToJSON(user_2);
printf("repeating user:\n%s\n", cJSON_Print(jsonuser_2));
}
int main() {
test_user(1);
test_user(0);
printf("Hello world \n");
return 0;
}
#endif // user_MAIN
#endif // user_TEST