Skip to content

Commit e9c1346

Browse files
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
1 parent 166aae6 commit e9c1346

File tree

15 files changed

+580
-6
lines changed

15 files changed

+580
-6
lines changed

modules/openapi-generator/src/main/java/org/openapitools/codegen/languages/CLibcurlClientCodegen.java

Lines changed: 100 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -87,7 +87,7 @@ public CLibcurlClientCodegen() {
8787
embeddedTemplateDir = templateDir = "C-libcurl";
8888

8989
// TODO add auto-generated test files
90-
//modelTestTemplateFiles.put("model_test.mustache", ".c");
90+
modelTestTemplateFiles.put("model_test.mustache", ".c");
9191
//apiTestTemplateFiles.put("api_test.mustache", ".c");
9292

9393
// default HIDE_GENERATION_TIMESTAMP to true
@@ -321,6 +321,104 @@ public String toDefaultValue(Schema p) {
321321
return null;
322322
}
323323

324+
@Override
325+
public String toExampleValue(Schema schema) {
326+
String example = super.toExampleValue(schema);
327+
328+
if (ModelUtils.isNullType(schema) && null != example) {
329+
// The 'null' type is allowed in OAS 3.1 and above. It is not supported by OAS 3.0.x,
330+
// though this tooling supports it.
331+
return "NULL";
332+
}
333+
// correct "'"s into "'"s after toString()
334+
if (ModelUtils.isStringSchema(schema) && schema.getDefault() != null) {
335+
example = (String) schema.getDefault();
336+
}
337+
if (StringUtils.isNotBlank(example) && !"null".equals(example)) {
338+
if (ModelUtils.isStringSchema(schema)) {
339+
example = "\"" + example + "\"";
340+
}
341+
return example;
342+
}
343+
344+
if (schema.getEnum() != null && !schema.getEnum().isEmpty()) {
345+
// Enum case:
346+
example = schema.getEnum().get(0).toString();
347+
/* if (ModelUtils.isStringSchema(schema)) {
348+
example = "'" + escapeText(example) + "'";
349+
}*/
350+
if (null == example)
351+
LOGGER.warn("Empty enum. Cannot built an example!");
352+
353+
return example;
354+
} else if (null != schema.get$ref()) {
355+
// $ref case:
356+
Map<String, Schema> allDefinitions = ModelUtils.getSchemas(this.openAPI);
357+
String ref = ModelUtils.getSimpleRef(schema.get$ref());
358+
if (allDefinitions != null) {
359+
Schema refSchema = allDefinitions.get(ref);
360+
if (null == refSchema) {
361+
return "None";
362+
} else {
363+
String refTitle = refSchema.getTitle();
364+
if (StringUtils.isBlank(refTitle) || "null".equals(refTitle)) {
365+
refSchema.setTitle(ref);
366+
}
367+
return toExampleValue(refSchema);
368+
}
369+
} else {
370+
LOGGER.warn("allDefinitions not defined in toExampleValue!\n");
371+
}
372+
}
373+
if (ModelUtils.isDateSchema(schema)) {
374+
example = "\"2013-10-20\"";
375+
return example;
376+
} else if (ModelUtils.isDateTimeSchema(schema)) {
377+
example = "\"2013-10-20T19:20:30+01:00\"";
378+
return example;
379+
} else if (ModelUtils.isBinarySchema(schema)) {
380+
example = "bytes(b'blah')";
381+
return example;
382+
} else if (ModelUtils.isByteArraySchema(schema)) {
383+
example = "YQ==";
384+
} else if (ModelUtils.isStringSchema(schema)) {
385+
// a BigDecimal:
386+
if ("Number".equalsIgnoreCase(schema.getFormat())) {return "1";}
387+
if (StringUtils.isNotBlank(schema.getPattern())) return "'a'"; // I cheat here, since it would be too complicated to generate a string from a regexp
388+
int len = 0;
389+
if (null != schema.getMinLength()) len = schema.getMinLength().intValue();
390+
if (len < 1) len = 1;
391+
example = "";
392+
for (int i=0;i<len;i++) example += i;
393+
} else if (ModelUtils.isIntegerSchema(schema)) {
394+
if (schema.getMinimum() != null)
395+
example = schema.getMinimum().toString();
396+
else
397+
example = "56";
398+
} else if (ModelUtils.isNumberSchema(schema)) {
399+
if (schema.getMinimum() != null)
400+
example = schema.getMinimum().toString();
401+
else
402+
example = "1.337";
403+
} else if (ModelUtils.isBooleanSchema(schema)) {
404+
example = "1";
405+
} else if (ModelUtils.isArraySchema(schema)) {
406+
example = "list_create()";
407+
} else if (ModelUtils.isMapSchema(schema)) {
408+
example = "list_create()";
409+
} else if (ModelUtils.isObjectSchema(schema)) {
410+
return null; // models are managed at moustache level
411+
} else {
412+
LOGGER.warn("Type " + schema.getType() + " not handled properly in toExampleValue");
413+
}
414+
415+
if (ModelUtils.isStringSchema(schema)) {
416+
example = "\"" + escapeText(example) + "\"";
417+
}
418+
419+
return example;
420+
}
421+
324422
@Override
325423
public String getSchemaType(Schema schema) {
326424
String openAPIType = super.getSchemaType(schema);
@@ -431,7 +529,7 @@ public String toApiTestFilename(String name) {
431529

432530
@Override
433531
public String toModelTestFilename(String name) {
434-
return ("test_" + toModelFilename(name)).replaceAll("_", "-");
532+
return ("test_" + toModelFilename(name));
435533
}
436534

437535
@Override

modules/openapi-generator/src/main/resources/C-libcurl/model-header.mustache

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,9 @@
1111
#include "../external/cJSON.h"
1212
#include "../include/list.h"
1313
#include "../include/keyValuePair.h"
14+
15+
typedef struct {{classname}}_t {{classname}}_t;
16+
1417
{{#imports}}
1518
#include "{{{.}}}.h"
1619
{{/imports}}
Lines changed: 67 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,74 @@
1+
{{#models}}
2+
{{#model}}
3+
#ifndef {{classFilename}}_TEST
4+
#define {{classFilename}}_TEST
5+
6+
// the following is to include only the main from the first c file
7+
#ifndef TEST_MAIN
8+
#define TEST_MAIN
9+
#define {{classFilename}}_MAIN
10+
#endif // TEST_MAIN
11+
112
#include <stdlib.h>
213
#include <string.h>
314
#include <stdio.h>
4-
#include "cJSON.h"
5-
{{#imports}}{{{import}}}
6-
{{/imports}}
15+
#include <stdbool.h>
16+
#include "../external/cJSON.h"
17+
18+
#include "../model/{{classFilename}}.h"
19+
{{classname}}_t* instantiate_{{classname}}(int include_optional);
20+
21+
{{#vars}}{{#isModel}}{{#isEnum}}
22+
// it is enum. Work in Progress
23+
{{/isEnum}}{{^isEnum}}#include "test_{{{dataType}}}.c"
24+
{{/isEnum}}{{/isModel}}{{/vars}}
25+
26+
{{classname}}_t* instantiate_{{classname}}(int include_optional) {
27+
{{classname}}_t* {{classname}} = NULL;
28+
if (include_optional) {
29+
{{classname}} = {{classname}}_create(
30+
{{#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
31+
{{/isEnum}}{{^isEnum}} // false, not to have infinite recursion
32+
instantiate_{{{dataType}}}(0){{/isEnum}}{{/isModel}}{{^isModel}}0{{/isModel}}{{/example}}{{#hasMore}},{{/hasMore}}
33+
{{/vars}}
34+
);
35+
} else {
36+
{{classname}} = {{classname}}_create(
37+
{{#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
38+
{{/isEnum}}{{^isEnum}}NULL{{/isEnum}}{{/isModel}}{{^isModel}}0{{/isModel}}{{/example}}{{#hasMore}},{{/hasMore}}
39+
{{/vars}}
40+
);
41+
}
42+
43+
return {{classname}};
44+
}
45+
46+
47+
#ifdef {{classFilename}}_MAIN
48+
49+
void test_{{classname}}(int include_optional) {
50+
{{classname}}_t* {{classname}}_1 = instantiate_{{classname}}(include_optional);
51+
52+
cJSON* json{{classname}}_1 = {{classname}}_convertToJSON({{classname}}_1);
53+
printf("{{classname}} :\n%s\n", cJSON_Print(json{{classname}}_1));
54+
{{classname}}_t* {{classname}}_2 = {{classname}}_parseFromJSON(json{{classname}}_1);
55+
cJSON* json{{classname}}_2 = {{classname}}_convertToJSON({{classname}}_2);
56+
printf("repeating {{classname}}:\n%s\n", cJSON_Print(json{{classname}}_2));
57+
}
758

859
int main() {
9-
printf("Hello world \n");
60+
{{#models}}
61+
{{#model}}
62+
test_{{classname}}(1);
63+
test_{{classname}}(0);
64+
{{/model}}
65+
{{/models}}
1066

67+
printf("Hello world \n");
68+
return 0;
1169
}
70+
71+
#endif // {{classFilename}}_MAIN
72+
#endif // {{classFilename}}_TEST
73+
{{/model}}
74+
{{/models}}

samples/client/petstore/c/model/api_response.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,9 @@
1212
#include "../include/list.h"
1313
#include "../include/keyValuePair.h"
1414

15+
typedef struct api_response_t api_response_t;
16+
17+
1518

1619

1720
typedef struct api_response_t {

samples/client/petstore/c/model/category.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,9 @@
1212
#include "../include/list.h"
1313
#include "../include/keyValuePair.h"
1414

15+
typedef struct category_t category_t;
16+
17+
1518

1619

1720
typedef struct category_t {

samples/client/petstore/c/model/order.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,9 @@
1212
#include "../include/list.h"
1313
#include "../include/keyValuePair.h"
1414

15+
typedef struct order_t order_t;
16+
17+
1518
// Enum STATUS for order
1619

1720
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;

samples/client/petstore/c/model/pet.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,9 @@
1111
#include "../external/cJSON.h"
1212
#include "../include/list.h"
1313
#include "../include/keyValuePair.h"
14+
15+
typedef struct pet_t pet_t;
16+
1417
#include "category.h"
1518
#include "tag.h"
1619

samples/client/petstore/c/model/tag.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,9 @@
1212
#include "../include/list.h"
1313
#include "../include/keyValuePair.h"
1414

15+
typedef struct tag_t tag_t;
16+
17+
1518

1619

1720
typedef struct tag_t {

samples/client/petstore/c/model/user.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,9 @@
1212
#include "../include/list.h"
1313
#include "../include/keyValuePair.h"
1414

15+
typedef struct user_t user_t;
16+
17+
1518

1619

1720
typedef struct user_t {
Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,62 @@
1+
#ifndef api_response_TEST
2+
#define api_response_TEST
3+
4+
// the following is to include only the main from the first c file
5+
#ifndef TEST_MAIN
6+
#define TEST_MAIN
7+
#define api_response_MAIN
8+
#endif // TEST_MAIN
9+
10+
#include <stdlib.h>
11+
#include <string.h>
12+
#include <stdio.h>
13+
#include <stdbool.h>
14+
#include "../external/cJSON.h"
15+
16+
#include "../model/api_response.h"
17+
api_response_t* instantiate_api_response(int include_optional);
18+
19+
20+
21+
api_response_t* instantiate_api_response(int include_optional) {
22+
api_response_t* api_response = NULL;
23+
if (include_optional) {
24+
api_response = api_response_create(
25+
56,
26+
"0",
27+
"0"
28+
);
29+
} else {
30+
api_response = api_response_create(
31+
56,
32+
"0",
33+
"0"
34+
);
35+
}
36+
37+
return api_response;
38+
}
39+
40+
41+
#ifdef api_response_MAIN
42+
43+
void test_api_response(int include_optional) {
44+
api_response_t* api_response_1 = instantiate_api_response(include_optional);
45+
46+
cJSON* jsonapi_response_1 = api_response_convertToJSON(api_response_1);
47+
printf("api_response :\n%s\n", cJSON_Print(jsonapi_response_1));
48+
api_response_t* api_response_2 = api_response_parseFromJSON(jsonapi_response_1);
49+
cJSON* jsonapi_response_2 = api_response_convertToJSON(api_response_2);
50+
printf("repeating api_response:\n%s\n", cJSON_Print(jsonapi_response_2));
51+
}
52+
53+
int main() {
54+
test_api_response(1);
55+
test_api_response(0);
56+
57+
printf("Hello world \n");
58+
return 0;
59+
}
60+
61+
#endif // api_response_MAIN
62+
#endif // api_response_TEST
Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,60 @@
1+
#ifndef category_TEST
2+
#define category_TEST
3+
4+
// the following is to include only the main from the first c file
5+
#ifndef TEST_MAIN
6+
#define TEST_MAIN
7+
#define category_MAIN
8+
#endif // TEST_MAIN
9+
10+
#include <stdlib.h>
11+
#include <string.h>
12+
#include <stdio.h>
13+
#include <stdbool.h>
14+
#include "../external/cJSON.h"
15+
16+
#include "../model/category.h"
17+
category_t* instantiate_category(int include_optional);
18+
19+
20+
21+
category_t* instantiate_category(int include_optional) {
22+
category_t* category = NULL;
23+
if (include_optional) {
24+
category = category_create(
25+
56,
26+
"0"
27+
);
28+
} else {
29+
category = category_create(
30+
56,
31+
"0"
32+
);
33+
}
34+
35+
return category;
36+
}
37+
38+
39+
#ifdef category_MAIN
40+
41+
void test_category(int include_optional) {
42+
category_t* category_1 = instantiate_category(include_optional);
43+
44+
cJSON* jsoncategory_1 = category_convertToJSON(category_1);
45+
printf("category :\n%s\n", cJSON_Print(jsoncategory_1));
46+
category_t* category_2 = category_parseFromJSON(jsoncategory_1);
47+
cJSON* jsoncategory_2 = category_convertToJSON(category_2);
48+
printf("repeating category:\n%s\n", cJSON_Print(jsoncategory_2));
49+
}
50+
51+
int main() {
52+
test_category(1);
53+
test_category(0);
54+
55+
printf("Hello world \n");
56+
return 0;
57+
}
58+
59+
#endif // category_MAIN
60+
#endif // category_TEST

0 commit comments

Comments
 (0)