Skip to content
New issue

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

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

Already on GitHub? Sign in to your account

Tests for models for C-libcurl generator #5699

Merged
merged 4 commits into from
Apr 5, 2020
Merged
Show file tree
Hide file tree
Changes from 3 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@

import io.swagger.v3.oas.models.OpenAPI;
import io.swagger.v3.oas.models.info.Info;
import io.swagger.v3.oas.models.media.ArraySchema;
import io.swagger.v3.oas.models.media.Schema;
import org.apache.commons.io.FilenameUtils;
import org.apache.commons.lang3.StringUtils;
Expand Down Expand Up @@ -87,7 +88,7 @@ public CLibcurlClientCodegen() {
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
Expand Down Expand Up @@ -321,6 +322,104 @@ public String toDefaultValue(Schema p) {
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);
Expand Down Expand Up @@ -431,7 +530,8 @@ public String toApiTestFilename(String name) {

@Override
public String toModelTestFilename(String name) {
return ("test_" + toModelFilename(name)).replaceAll("_", "-");
return ("test_" + toModelFilename(name));
// return ("test_" + toModelFilename(name)).replaceAll("_", "-");
}

@Override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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}}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,11 +1,105 @@
{{#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}}// michele model enum : {{/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}}
{{#isPrimitiveType}}//primitive{{/isPrimitiveType}}
{{#isContainer}}
{{#isListContainer}}//list {{dataType}}_t *{{/isListContainer}}
{{#isMapContainer}}// map {{dataType}}{{/isMapContainer}}
{{/isContainer}}
{{#isModel}}
{{#isEnum}}// enum {{datatypeWithEnum}}_e{{/isEnum}}
{{^isEnum}}// modello normale {{{dataType}}}_t *{{/isEnum}}
{{/isModel}}
{{^example}}
{{#isModel}}
{{#isEnum}}// enum {{datatypeWithEnum}}_e{{/isEnum}}
{{^isEnum}}instantiate_{{{dataType}}}(0) // false, not to have infinite recursion {{/isEnum}}
{{/isModel}}
{{^isModel}}
0
{{/isModel}}
{{/example}}{{#hasMore}},{{/hasMore}} // {{name}}
{{/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{{/isEnum}}
{{^isEnum}}NULL{{/isEnum}}
{{/isModel}}
{{^isModel}}
0
{{/isModel}}
{{/example}}{{#hasMore}},{{/hasMore}} // {{name}}
{{/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}}
3 changes: 3 additions & 0 deletions samples/client/petstore/c/model/api_response.h
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand Down
3 changes: 3 additions & 0 deletions samples/client/petstore/c/model/category.h
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,9 @@
#include "../include/list.h"
#include "../include/keyValuePair.h"

typedef struct category_t category_t;




typedef struct category_t {
Expand Down
3 changes: 3 additions & 0 deletions samples/client/petstore/c/model/order.h
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down
3 changes: 3 additions & 0 deletions samples/client/petstore/c/model/pet.h
Original file line number Diff line number Diff line change
Expand Up @@ -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"

Expand Down
3 changes: 3 additions & 0 deletions samples/client/petstore/c/model/tag.h
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,9 @@
#include "../include/list.h"
#include "../include/keyValuePair.h"

typedef struct tag_t tag_t;




typedef struct tag_t {
Expand Down
3 changes: 3 additions & 0 deletions samples/client/petstore/c/model/user.h
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,9 @@
#include "../include/list.h"
#include "../include/keyValuePair.h"

typedef struct user_t user_t;




typedef struct user_t {
Expand Down
73 changes: 73 additions & 0 deletions samples/client/petstore/c/unit-test/test_api_response.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
#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
//primitive
, // code
"0"
//primitive
, // type
"0"
//primitive
// message
);
} else {
api_response = api_response_create(
56
, // code
"0"
, // type
"0"
// message
);
}

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
Loading