Skip to content
Permalink
Browse files

R client refactoring (#2215)

* [R] fix namespace, use 2-space indentation (#2105)

* fix namespace, indentation

* use 2-space indentation in model files

* update gitignore

* use PascalCase for function naming (#2106)

* [R] improve .travis.yml, .Rbuildignore (#2109)

* update travis

* enhance travis.yml

* update travis, .Rbuildignore

* [R] Add auto-generated documentations, change parameter naming (#2114)

* add auto-generated doc for r client

* remove module name

* replace nil with void

* [R] fix object serialization to JSON (#2129)

* fix object serialization

* fix array property seriziation

* fix deserializing array of string

* fix array of object deserialization

* [R] Fix return type (#2140)

* fix return type

* update r petstore sample

* add auto-generated tests (#2141)

* rename file to conform to style guide (#2142)

* add authenticaiton support to R (#2153)

[R] Add authentication support, minor ApiClient refactor

* rename test files

* [R] various improvements and bug fixes (#2162)

* fix api keys in headers

* use optional parameter in function signature

* fix property naming

* fix doc assignment operator

* [R] fix base64 encode (#2171)

* fix base64 encode

* fix basic http auth

* fix typo, update instruction (#2203)

* rename test files to conform to style guide (#2206)

* [R] improve class constructor (#2208)

* update constructor with optional parameter, default value

* update r petstore sample

* clean up files

* regenerate files

* Revert "rename test files to conform to style guide (#2206)"

This reverts commit 90a6302.

* fix query parameter in api client (#2214)
  • Loading branch information...
wing328 committed Feb 23, 2019
1 parent 7486438 commit e6658278ad47e1b5200eb98e4528f2cc09ece6e4
Showing with 3,123 additions and 1,098 deletions.
  1. +2 −0 .gitignore
  2. +202 −19 modules/openapi-generator/src/main/java/org/openapitools/codegen/languages/RClientCodegen.java
  3. +13 −1 modules/openapi-generator/src/main/resources/r/.travis.yml
  4. +5 −5 modules/openapi-generator/src/main/resources/r/{response.mustache → ApiResponse.mustache}
  5. +18 −0 modules/openapi-generator/src/main/resources/r/NAMESPACE.mustache
  6. +68 −8 modules/openapi-generator/src/main/resources/r/README.mustache
  7. +3 −0 modules/openapi-generator/src/main/resources/r/Rbuildignore.mustache
  8. +54 −33 modules/openapi-generator/src/main/resources/r/api.mustache
  9. +65 −36 modules/openapi-generator/src/main/resources/r/api_client.mustache
  10. +48 −18 modules/openapi-generator/src/main/resources/r/api_doc.mustache
  11. +29 −0 modules/openapi-generator/src/main/resources/r/api_test.mustache
  12. +1 −1 modules/openapi-generator/src/main/resources/r/description.mustache
  13. +155 −107 modules/openapi-generator/src/main/resources/r/model.mustache
  14. +2 −4 modules/openapi-generator/src/main/resources/r/model_doc.mustache
  15. +23 −0 modules/openapi-generator/src/main/resources/r/model_test.mustache
  16. +4 −0 modules/openapi-generator/src/main/resources/r/testthat.mustache
  17. +3 −0 samples/client/petstore/R/.Rbuildignore
  18. +13 −1 samples/client/petstore/R/.travis.yml
  19. +1 −1 samples/client/petstore/R/DESCRIPTION
  20. +10 −0 samples/client/petstore/R/NAMESPACE
  21. +0 −71 samples/client/petstore/R/R/ApiClient.r
  22. +0 −100 samples/client/petstore/R/R/ApiResponse.r
  23. +0 −24 samples/client/petstore/R/R/Element.r
  24. +0 −159 samples/client/petstore/R/R/Order.r
  25. +0 −200 samples/client/petstore/R/R/User.r
  26. +100 −0 samples/client/petstore/R/R/api_client.R
  27. +5 −5 samples/client/petstore/R/R/{Response.r → api_response.R}
  28. +18 −23 samples/client/petstore/R/R/{Category.r → category.R}
  29. +92 −0 samples/client/petstore/R/R/model_api_response.R
  30. +142 −0 samples/client/petstore/R/R/order.R
  31. +62 −70 samples/client/petstore/R/R/pet.R
  32. +131 −80 samples/client/petstore/R/R/{PetApi.r → pet_api.R}
  33. +56 −37 samples/client/petstore/R/R/{StoreApi.r → store_api.R}
  34. +18 −23 samples/client/petstore/R/R/{Tag.r → tag.R}
  35. +177 −0 samples/client/petstore/R/R/user.R
  36. +103 −64 samples/client/petstore/R/R/{UserApi.r → user_api.R}
  37. +89 −8 samples/client/petstore/R/README.md
  38. +10 −0 samples/client/petstore/R/docs/ApiResponse.md
  39. +9 −0 samples/client/petstore/R/docs/Category.md
  40. +10 −0 samples/client/petstore/R/docs/ModelApiResponse.md
  41. +13 −0 samples/client/petstore/R/docs/Order.md
  42. +13 −0 samples/client/petstore/R/docs/Pet.md
  43. +348 −0 samples/client/petstore/R/docs/PetApi.md
  44. +167 −0 samples/client/petstore/R/docs/StoreApi.md
  45. +9 −0 samples/client/petstore/R/docs/Tag.md
  46. +15 −0 samples/client/petstore/R/docs/User.md
  47. +320 −0 samples/client/petstore/R/docs/UserApi.md
  48. +4 −0 samples/client/petstore/R/tests/testthat.R
  49. +21 −0 samples/client/petstore/R/tests/testthat/test_category.R
  50. +28 −0 samples/client/petstore/R/tests/testthat/test_model_api_response.R
  51. +50 −0 samples/client/petstore/R/tests/testthat/test_order.R
  52. +50 −0 samples/client/petstore/R/tests/testthat/test_pet.R
  53. +103 −0 samples/client/petstore/R/tests/testthat/test_pet_api.R
  54. +53 −0 samples/client/petstore/R/tests/testthat/test_store_api.R
  55. +21 −0 samples/client/petstore/R/tests/testthat/test_tag.R
  56. +64 −0 samples/client/petstore/R/tests/testthat/test_user.R
  57. +99 −0 samples/client/petstore/R/tests/testthat/test_user_api.R
  58. +4 −0 samples/client/petstore/R/testthat.R
@@ -193,6 +193,8 @@ samples/client/petstore/haskell-http-client/docs/quick-jump.css

# R
.Rproj.user
samples/client/petstore/R/**/petstore.Rcheck/
samples/client/petstore/R/**/*.tar.gz

# elixir
samples/client/petstore/elixir/_build/
@@ -17,8 +17,10 @@

package org.openapitools.codegen.languages;

import io.swagger.v3.oas.models.examples.Example;
import io.swagger.v3.oas.models.media.ArraySchema;
import io.swagger.v3.oas.models.media.Schema;
import io.swagger.v3.oas.models.parameters.Parameter;
import org.apache.commons.lang3.StringUtils;
import org.openapitools.codegen.*;
import org.openapitools.codegen.utils.ModelUtils;
@@ -27,6 +29,7 @@

import java.io.File;
import java.util.*;
import java.util.regex.Pattern;

import static org.openapitools.codegen.utils.StringUtils.camelize;
import static org.openapitools.codegen.utils.StringUtils.underscore;
@@ -38,6 +41,7 @@
protected String packageVersion = "1.0.0";
protected String apiDocPath = "docs/";
protected String modelDocPath = "docs/";
protected String testFolder = "tests/testthat";

public CodegenType getTag() {
return CodegenType.CLIENT;
@@ -54,8 +58,8 @@ public String getHelp() {
public RClientCodegen() {
super();
outputFolder = "generated-code/r";
modelTemplateFiles.put("model.mustache", ".r");
apiTemplateFiles.put("api.mustache", ".r");
modelTemplateFiles.put("model.mustache", ".R");
apiTemplateFiles.put("api.mustache", ".R");

modelDocTemplateFiles.put("model_doc.mustache", ".md");
apiDocTemplateFiles.put("api_doc.mustache", ".md");
@@ -70,7 +74,9 @@ public RClientCodegen() {
// reserved words: https://stat.ethz.ch/R-manual/R-devel/library/base/html/Reserved.html
"if", "else", "repeat", "while", "function", "for", "in",
"next", "break", "TRUE", "FALSE", "NULL", "Inf", "NaN",
"NA", "NA_integer_", "NA_real_", "NA_complex_", "NA_character_"
"NA", "NA_integer_", "NA_real_", "NA_complex_", "NA_character_",
// reserved words in API client
"ApiResponse"
)
);

@@ -130,11 +136,11 @@ public void processOpts() {
additionalProperties.put("apiDocPath", apiDocPath);
additionalProperties.put("modelDocPath", modelDocPath);

apiTestTemplateFiles.clear(); // TODO: add api test template
modelTestTemplateFiles.clear(); // TODO: add model test template
modelTestTemplateFiles.put("model_test.mustache", ".R");
apiTestTemplateFiles.put("api_test.mustache", ".R");

apiDocTemplateFiles.clear(); // TODO: add api doc template
modelDocTemplateFiles.clear(); // TODO: add model doc template
modelDocTemplateFiles.put("model_doc.mustache", ".md");
apiDocTemplateFiles.put("api_doc.mustache", ".md");

modelPackage = packageName;
apiPackage = packageName;
@@ -145,10 +151,11 @@ public void processOpts() {
supportingFiles.add(new SupportingFile("description.mustache", "", "DESCRIPTION"));
supportingFiles.add(new SupportingFile("Rbuildignore.mustache", "", ".Rbuildignore"));
supportingFiles.add(new SupportingFile(".travis.yml", "", ".travis.yml"));
supportingFiles.add(new SupportingFile("response.mustache", "/R", "Response.r"));
supportingFiles.add(new SupportingFile("element.mustache", "/R", "Element.r"));
supportingFiles.add(new SupportingFile("api_client.mustache", "/R", "ApiClient.r"));
supportingFiles.add(new SupportingFile("ApiResponse.mustache", File.separator + "R", "api_response.R"));
//supportingFiles.add(new SupportingFile("element.mustache", File.separator + "R", "Element.R"));
supportingFiles.add(new SupportingFile("api_client.mustache", File.separator + "R", "api_client.R"));
supportingFiles.add(new SupportingFile("NAMESPACE.mustache", "", "NAMESPACE"));
supportingFiles.add(new SupportingFile("testthat.mustache", File.separator + "tests", "testthat.R"));
}

@Override
@@ -180,7 +187,7 @@ public String modelFileFolder() {
}

@Override
public String toVarName(String name) {
public String toParamName(String name) {
// replace - with _ e.g. created-at => created_at
name = sanitizeName(name.replaceAll("-", "_"));

@@ -200,21 +207,22 @@ public String toVarName(String name) {
if (name.matches("^\\d.*"))
name = "Var" + name;

return name;
return name.replace("_", ".");
}

@Override
public String toParamName(String name) {
return toVarName(name);
public String toVarName(String name) {
// don't do anything as we'll put property name inside ` `, e.g. `date-time`
return name;
}

@Override
public String toModelName(String name) {
return toModelFilename(name);
public String toModelFilename(String name) {
return underscore(toModelName(name));
}

@Override
public String toModelFilename(String name) {
public String toModelName(String name) {
if (!StringUtils.isEmpty(modelNamePrefix)) {
name = modelNamePrefix + "_" + name;
}
@@ -246,7 +254,7 @@ public String toApiFilename(String name) {
name = name.replaceAll("-", "_"); // FIXME: a parameter should not be assigned. Also declare the methods parameters as 'final'.

// e.g. PetApi.r => pet_api.r
return camelize(name + "_api");
return underscore(name + "_api");
}

@Override
@@ -327,7 +335,7 @@ public String toOperationId(String operationId) {
sanitizedOperationId = "call_" + sanitizedOperationId;
}

return underscore(sanitizedOperationId);
return camelize(sanitizedOperationId);
}

@Override
@@ -450,4 +458,179 @@ public String toEnumName(CodegenProperty property) {
return enumName;
}
}

@Override
public void setParameterExampleValue(CodegenParameter p) {
String example;

if (p.defaultValue == null) {
example = p.example;
} else {
p.example = p.defaultValue;
return;
}

String type = p.baseType;
if (type == null) {
type = p.dataType;
}

if ("character".equals(type)) {
if (example == null) {
example = p.paramName + "_example";
}
example = "'" + escapeText(example) + "'";
} else if ("integer".equals(type)) {
if (example == null) {
example = "56";
}
} else if ("numeric".equals(type)) {
if (example == null) {
example = "3.4";
}
} else if ("data.frame".equals(type)) {
if (example == null) {
example = "/path/to/file";
}
example = "File.new('" + escapeText(example) + "')";
} else if (!languageSpecificPrimitives.contains(type)) {
// type is a model class, e.g. User
example = type + "$new()";
}

if (example == null) {
example = "NULL";
} else if (Boolean.TRUE.equals(p.isListContainer)) {
example = "[" + example + "]";
} else if (Boolean.TRUE.equals(p.isMapContainer)) {
example = "{'key' => " + example + "}";
}

p.example = example;
}

/**
* Return the example value of the parameter. Overrides the
* setParameterExampleValue(CodegenParameter, Parameter) method in
* DefaultCodegen to always call setParameterExampleValue(CodegenParameter)
* in this class, which adds single quotes around strings from the
* x-example property.
*
* @param codegenParameter Codegen parameter
* @param parameter Parameter
*/
public void setParameterExampleValue(CodegenParameter codegenParameter, Parameter parameter) {
if (parameter.getExample() != null) {
codegenParameter.example = parameter.getExample().toString();
} else if (parameter.getExamples() != null && !parameter.getExamples().isEmpty()) {
Example example = parameter.getExamples().values().iterator().next();
if (example.getValue() != null) {
codegenParameter.example = example.getValue().toString();
}
} else {
Schema schema = parameter.getSchema();
if (schema != null && schema.getExample() != null) {
codegenParameter.example = schema.getExample().toString();
}
}

setParameterExampleValue(codegenParameter);
}

/**
* Return the default value of the property
* @param p OpenAPI property object
* @return string presentation of the default value of the property
*/
@Override
public String toDefaultValue(Schema p) {
if (ModelUtils.isBooleanSchema(p)) {
if (p.getDefault() != null) {
if (Boolean.valueOf(p.getDefault().toString()) == false)
return "FALSE";
else
return "TRUE";
}
// include fallback to example, default defined as server only
// example is not defined as server only
if (p.getExample() != null) {
if (Boolean.valueOf(p.getExample().toString()) == false)
return "FALSE";
else
return "TRUE";
}
} else if (ModelUtils.isDateSchema(p)) {
// TODO
} else if (ModelUtils.isDateTimeSchema(p)) {
// TODO
} else if (ModelUtils.isNumberSchema(p)) {
if (p.getDefault() != null) {
return p.getDefault().toString();
}
// default numbers are not yet returned by v2 spec openAPI results
// https://github.com/swagger-api/swagger-parser/issues/971
// include fallback to example, default defined as server only
// example is not defined as server only
if (p.getExample() != null) {
return p.getExample().toString();
}
} else if (ModelUtils.isIntegerSchema(p)) {
if (p.getDefault() != null) {
return p.getDefault().toString();
}
// default integers are not yet returned by v2 spec openAPI results
// https://github.com/swagger-api/swagger-parser/issues/971
// include fallback to example, default defined as server only
// example is not defined as server only
if (p.getExample() != null) {
return p.getExample().toString();
}
} else if (ModelUtils.isStringSchema(p)) {
if (p.getDefault() != null) {
if (Pattern.compile("\r\n|\r|\n").matcher((String) p.getDefault()).find())
return "'''" + p.getDefault() + "'''";
else
return "'" + p.getDefault() + "'";
}
// include fallback to example, default defined as server only
// example is not defined as server only
if (p.getExample() != null) {
if (Pattern.compile("\r\n|\r|\n").matcher((String) p.getExample()).find())
return "'''" + p.getExample() + "'''";
else
return "'" + p.getExample() + "'";
}
} else if (ModelUtils.isArraySchema(p)) {
if (p.getDefault() != null) {
return p.getDefault().toString();
}
// include fallback to example, default defined as server only
// example is not defined as server only
if (p.getExample() != null) {
return p.getExample().toString();
}
}

return null;
}

@Override
public String apiTestFileFolder() {
return outputFolder + File.separator + testFolder;
}

@Override
public String modelTestFileFolder() {
return outputFolder + File.separator + testFolder;
}

@Override
public String toApiTestFilename(String name) {
return "test_" + toApiFilename(name);
}

@Override
public String toModelTestFilename(String name) {
return "test_" + toModelFilename(name);
}
}
@@ -1,3 +1,15 @@
# ref: https://docs.travis-ci.com/user/languages/r/
language: r
cache: packages
cache:
directories:
- /home/travis/R/Library
r_packages:
- jsonlite
- httr
# uncomment below to install deps with devtools
#install:
#- R -e 'devtools::install_deps(dep = T)'
script:
- R CMD build .
- R CMD check *tar.gz
- R CMD INSTALL *tar.gz
@@ -1,9 +1,9 @@
#' Response Class
#' ApiResponse Class
#'
#' Response Class
#' ApiResponse Class
#' @export
Response <- R6::R6Class(
'Response',
ApiResponse <- R6::R6Class(
'ApiResponse',
public = list(
content = NULL,
response = NULL,
@@ -12,4 +12,4 @@ Response <- R6::R6Class(
self$response <- response
}
)
)
)
@@ -1,8 +1,26 @@
# Generated by openapi-generator: https://openapi-generator.tech
# Do not edit by hand

# Core
export(ApiClient)
export(ApiResponse)

# Models
{{#models}}
{{#model}}
export({{{classname}}})
{{/model}}
{{/models}}

# APIs
{{#apiInfo}}
{{#apis}}
{{#operations}}
{{#operation}}
{{#-first}}
export({{{classname}}})
{{/-first}}
{{/operation}}
{{/operations}}
{{/apis}}
{{/apiInfo}}
Oops, something went wrong.

0 comments on commit e665827

Please sign in to comment.
You can’t perform that action at this time.