[core] Refactor templating management (#6357)

* [core] Refactor templating management

This refactors template management to get logic out of DefaultGenerator
and to provide a cleaner API to template search and read/compile.

Deprecates MockDefaultGenerator, which is not a mock and causes
in-memory retention of file contents. Maintainers should prefer
executing a "dryRun" with new DefaultGenerator(true) or do true
mock/spies if evaluating template intermediaries is truly necessary.
Tests may read written files with lower overhead than the in-process
retention of those bytes.

This attempts to maintain some compatibility with existing templating
adapter interfaces. Any breaking change here would be unintentional but
minimal effort to retarget the new interface.

* Tests for dry run file outputs

* Update API usage in Meta, test TemplateManager

* Wait on lastModified, lookup by filename in SpringCodegenTest

* Test DefaultGenerator + ignore file

* Move config.processOpenAPI in DefaultGenerator

* Fix wrong use of libraries templateDirector (java)

The samples scripts for Java incorrectly referenced the libraries
directories directly rather than the upper-level Java directory. This
was incorrect usage of template directories, because the generator
expects to be given the "language" directory and perform a lookup for
missing templates in the order:

* user defined libraries directory
* user defined language root
* embedded libraries directory
* embedded language root
* _common directory

This is incorrect in our samples scripts because a user or maintainer
has the expectation that any template change to files at the Java/ root
should also be honored on generation if the script specifies a custom
template directory.

* Fix handlebars extension usage, clean up Meta tasks

HandlebarseEngineAdapter previously didn't handle files without
extensions in the same was as the MustacheEngineAdapter. This now allows
for files without extension (or dotfiles) to lookup in the same
location.

Meta tasks are cleaned up to use template manager only, rather than
attempting to create an "empty" generator to use the previous templating
specific methods.

* Update kotlin-multiplatform gradle wrapper

* Rename GraphQL .gitignore template

The .gitignore file is unable to load via classpath resource from the
graphql node server resource directory (for unknown reasons). Before
this change, the missing template would fail silently.

A .gitignore file may exist in other directories and load as expected.
Added a default .gitignore to _common as a fallback so as not to break
any custom generators which may also be failing silently.

* Log entire stacktrace in go sdk built by gradle in AppVeyor

* Rename PHP .gitignore to gitignore

Java resources may not load .gitignore, this follows suit with other
generators and uses "gitignore" (some use "gitignore.mustache").

* [php] Rename .gitignore templates to gitignore

* Use same classpath lookup in common locator

* [rust] Properly escape empty triple-braces

* [samples] Regenerate
This commit is contained in:
Jim Schubert 2020-05-30 00:19:03 -04:00 committed by GitHub
parent 74584eb734
commit a47e522fae
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
139 changed files with 3053 additions and 1941 deletions

View File

@ -50,7 +50,7 @@ build_script:
# install openapi-generator locally
- mvn --no-snapshot-updates --quiet clean install -Dorg.slf4j.simpleLogger.defaultLogLevel=error
# run the locally installed openapi-generator-gradle-plugin
- gradle -b modules\openapi-generator-gradle-plugin\samples\local-spec\build.gradle buildGoSdk --info
- gradle -b modules\openapi-generator-gradle-plugin\samples\local-spec\build.gradle buildGoSdk --stacktrace
test_script:
# restore test-related files
- copy /b/v/y CI\samples.ci\client\petstore\csharp\OpenAPIClient\src\Org.OpenAPITools.Test\Org.OpenAPITools.Test.csproj samples\client\petstore\csharp\OpenAPIClient\src\Org.OpenAPITools.Test\Org.OpenAPITools.Test.csproj

View File

@ -3,7 +3,7 @@
"generatorName": "java",
"inputSpec": "modules/openapi-generator/src/test/resources/2_0/petstore-with-fake-endpoints-models-for-testing.yaml",
"outputDir": "samples/client/petstore/java/feign",
"templateDir": "modules/openapi-generator/src/main/resources/Java/libraries/feign",
"templateDir": "modules/openapi-generator/src/main/resources/Java",
"additionalProperties": {
"hideGenerationTimestamp": true,
"booleanGetterPrefix": "is",

View File

@ -3,7 +3,7 @@
"generatorName": "java",
"inputSpec": "modules/openapi-generator/src/test/resources/2_0/petstore-with-fake-endpoints-models-for-testing.yaml",
"outputDir": "samples/client/petstore/java/feign10x",
"templateDir": "modules/openapi-generator/src/main/resources/Java/libraries/feign",
"templateDir": "modules/openapi-generator/src/main/resources/Java",
"additionalProperties": {
"hideGenerationTimestamp": true,
"booleanGetterPrefix": "is"

View File

@ -3,7 +3,7 @@
"generatorName": "java",
"inputSpec": "modules/openapi-generator/src/test/resources/2_0/petstore-with-fake-endpoints-models-for-testing.yaml",
"outputDir": "samples/client/petstore/java/google-api-client",
"templateDir": "modules/openapi-generator/src/main/resources/Java/libraries/google-api-client",
"templateDir": "modules/openapi-generator/src/main/resources/Java",
"additionalProperties": {
"hideGenerationTimestamp": true
}

View File

@ -3,7 +3,7 @@
"generatorName": "java",
"inputSpec": "modules/openapi-generator/src/test/resources/2_0/petstore-with-fake-endpoints-models-for-testing.yaml",
"outputDir": "samples/client/petstore/java/native",
"templateDir": "modules/openapi-generator/src/main/resources/Java/libraries/native",
"templateDir": "modules/openapi-generator/src/main/resources/Java",
"additionalProperties": {
"hideGenerationTimestamp": true
}

View File

@ -4,7 +4,7 @@
"generatorName": "java",
"inputSpec": "modules/openapi-generator/src/test/resources/2_0/petstore-with-fake-endpoints-models-for-testing.yaml",
"outputDir": "samples/client/petstore/java/okhttp-gson-parcelableModel",
"templateDir": "modules/openapi-generator/src/main/resources/Java/libraries/okhttp-gson",
"templateDir": "modules/openapi-generator/src/main/resources/Java",
"additionalProperties": {
"hideGenerationTimestamp": true,
"parcelableModel": true

View File

@ -3,7 +3,7 @@
"generatorName": "java",
"inputSpec": "modules/openapi-generator/src/test/resources/2_0/petstore-with-fake-endpoints-models-for-testing.yaml",
"outputDir": "samples/client/petstore/java/okhttp-gson",
"templateDir": "modules/openapi-generator/src/main/resources/Java/libraries/okhttp-gson",
"templateDir": "modules/openapi-generator/src/main/resources/Java",
"additionalProperties": {
"hideGenerationTimestamp": true
}

View File

@ -1,7 +1,7 @@
{
"generatorName": "java",
"inputSpec": "modules/openapi-generator/src/test/resources/2_0/petstore-with-fake-endpoints-models-for-testing.yaml",
"templateDir": "modules/openapi-generator/src/main/resources/Java/libraries/feign",
"templateDir": "modules/openapi-generator/src/main/resources/Java",
"outputDir": "samples/client/petstore/java/feign10x",
"additionalProperties": {
"hideGenerationTimestamp": true,

View File

@ -3,7 +3,7 @@
"generatorName": "java",
"inputSpec": "modules/openapi-generator/src/test/resources/2_0/petstore-with-fake-endpoints-models-for-testing.yaml",
"outputDir": "samples/client/petstore/java/rest-assured-jackson",
"templateDir": "modules/openapi-generator/src/main/resources/Java/libraries/rest-assured",
"templateDir": "modules/openapi-generator/src/main/resources/Java",
"additionalProperties": {
"hideGenerationTimestamp": true,
"booleanGetterPrefix": "is",

View File

@ -3,7 +3,7 @@
"generatorName": "java",
"inputSpec": "modules/openapi-generator/src/test/resources/2_0/petstore-with-fake-endpoints-models-for-testing.yaml",
"outputDir": "samples/client/petstore/java/rest-assured",
"templateDir": "modules/openapi-generator/src/main/resources/Java/libraries/rest-assured",
"templateDir": "modules/openapi-generator/src/main/resources/Java",
"additionalProperties": {
"hideGenerationTimestamp": true,
"booleanGetterPrefix": "is"

View File

@ -3,7 +3,7 @@
"generatorName": "java",
"inputSpec": "modules/openapi-generator/src/test/resources/2_0/petstore-with-fake-endpoints-models-for-testing.yaml",
"outputDir": "samples/client/petstore/java/retrofit2",
"templateDir": "modules/openapi-generator/src/main/resources/Java/libraries/retrofit2",
"templateDir": "modules/openapi-generator/src/main/resources/Java",
"additionalProperties": {
"hideGenerationTimestamp": true
}

View File

@ -3,7 +3,7 @@
"generatorName": "java",
"inputSpec": "modules/openapi-generator/src/test/resources/2_0/petstore-with-fake-endpoints-models-for-testing.yaml",
"outputDir": "samples/client/petstore/java/retrofit2rx",
"templateDir": "modules/openapi-generator/src/main/resources/Java/libraries/retrofit2",
"templateDir": "modules/openapi-generator/src/main/resources/Java",
"additionalProperties": {
"useRxJava": true,
"hideGenerationTimestamp": true

View File

@ -3,7 +3,7 @@
"generatorName": "java",
"inputSpec": "modules/openapi-generator/src/test/resources/2_0/petstore-with-fake-endpoints-models-for-testing.yaml",
"outputDir": "samples/client/petstore/java/retrofit2rx2",
"templateDir": "modules/openapi-generator/src/main/resources/Java/libraries/retrofit2",
"templateDir": "modules/openapi-generator/src/main/resources/Java",
"additionalProperties": {
"useRxJava2": true,
"hideGenerationTimestamp": true

View File

@ -3,7 +3,7 @@
"generatorName": "java",
"inputSpec": "modules/openapi-generator/src/test/resources/2_0/petstore-with-fake-endpoints-models-for-testing.yaml",
"outputDir": "samples/client/petstore/java/vertx",
"templateDir": "modules/openapi-generator/src/main/resources/Java/libraries/vertx",
"templateDir": "modules/openapi-generator/src/main/resources/Java",
"additionalProperties": {
"hideGenerationTimestamp": true
}

View File

@ -27,7 +27,7 @@ fi
# if you've executed sbt assembly previously it will use that instead.
export JAVA_OPTS="${JAVA_OPTS} -Xmx1024M -DloggerPath=conf/log4j.properties"
ags="generate -t modules/openapi-generator/src/main/resources/Java/libraries/feign -i modules/openapi-generator/src/test/resources/2_0/petstore-with-fake-endpoints-models-for-testing.yaml -g java -c bin/java-petstore-feign-10x.json -o samples/client/petstore/java/feign10x --additional-properties hideGenerationTimestamp=true,booleanGetterPrefix=is $@"
ags="generate -t modules/openapi-generator/src/main/resources/Java -i modules/openapi-generator/src/test/resources/2_0/petstore-with-fake-endpoints-models-for-testing.yaml -g java -c bin/java-petstore-feign-10x.json -o samples/client/petstore/java/feign10x --additional-properties hideGenerationTimestamp=true,booleanGetterPrefix=is $@"
echo "Removing files and folders under samples/client/petstore/java/feign10x/src/main"
rm -rf samples/client/petstore/java/feign10x/src/main

View File

@ -27,7 +27,7 @@ fi
# if you've executed sbt assembly previously it will use that instead.
export JAVA_OPTS="${JAVA_OPTS} -Xmx1024M -DloggerPath=conf/log4j.properties"
ags="generate -t modules/openapi-generator/src/main/resources/Java/libraries/google-api-client -i modules/openapi-generator/src/test/resources/2_0/petstore-with-fake-endpoints-models-for-testing.yaml -g java -c bin/java-petstore-google-api-client.json -o samples/client/petstore/java/google-api-client --additional-properties hideGenerationTimestamp=true $@"
ags="generate -t modules/openapi-generator/src/main/resources/Java -i modules/openapi-generator/src/test/resources/2_0/petstore-with-fake-endpoints-models-for-testing.yaml -g java -c bin/java-petstore-google-api-client.json -o samples/client/petstore/java/google-api-client --additional-properties hideGenerationTimestamp=true $@"
echo "Removing files and folders under samples/client/petstore/java/google-api-client/src/main"
rm -rf samples/client/petstore/java/google-api-client/src/main

View File

@ -27,7 +27,7 @@ fi
# if you've executed sbt assembly previously it will use that instead.
export JAVA_OPTS="${JAVA_OPTS} -Xmx1024M -DloggerPath=conf/log4j.properties"
ags="generate -t modules/openapi-generator/src/main/resources/Java/libraries/native -i modules/openapi-generator/src/test/resources/2_0/petstore-with-fake-endpoints-models-for-testing.yaml -g java -c bin/java-petstore-native.json -o samples/client/petstore/java/native-async --additional-properties hideGenerationTimestamp=true,asyncNative=true $@"
ags="generate -t modules/openapi-generator/src/main/resources/Java -i modules/openapi-generator/src/test/resources/2_0/petstore-with-fake-endpoints-models-for-testing.yaml -g java -c bin/java-petstore-native.json -o samples/client/petstore/java/native-async --additional-properties hideGenerationTimestamp=true,asyncNative=true $@"
echo "Removing files and folders under samples/client/petstore/java/httpclient/src/main"
rm -rf samples/client/petstore/java/native-async/src/main

View File

@ -27,7 +27,7 @@ fi
# if you've executed sbt assembly previously it will use that instead.
export JAVA_OPTS="${JAVA_OPTS} -Xmx1024M -DloggerPath=conf/log4j.properties"
ags="generate -t modules/openapi-generator/src/main/resources/Java/libraries/native -i modules/openapi-generator/src/test/resources/2_0/petstore-with-fake-endpoints-models-for-testing.yaml -g java -c bin/java-petstore-native.json -o samples/client/petstore/java/native --additional-properties hideGenerationTimestamp=true $@"
ags="generate -t modules/openapi-generator/src/main/resources/Java -i modules/openapi-generator/src/test/resources/2_0/petstore-with-fake-endpoints-models-for-testing.yaml -g java -c bin/java-petstore-native.json -o samples/client/petstore/java/native --additional-properties hideGenerationTimestamp=true $@"
echo "Removing files and folders under samples/client/petstore/java/httpclient/src/main"
rm -rf samples/client/petstore/java/native/src/main

View File

@ -27,7 +27,7 @@ fi
# if you've executed sbt assembly previously it will use that instead.
export JAVA_OPTS="${JAVA_OPTS} -Xmx1024M -DloggerPath=conf/log4j.properties"
ags="generate --artifact-id petstore-okhttp-gson-parcelableModel -t modules/openapi-generator/src/main/resources/Java/libraries/okhttp-gson -i modules/openapi-generator/src/test/resources/2_0/petstore-with-fake-endpoints-models-for-testing.yaml -g java -c bin/java-petstore-okhttp-gson.json -o samples/client/petstore/java/okhttp-gson-parcelableModel --additional-properties hideGenerationTimestamp=true,parcelableModel=true $@"
ags="generate --artifact-id petstore-okhttp-gson-parcelableModel -t modules/openapi-generator/src/main/resources/Java -i modules/openapi-generator/src/test/resources/2_0/petstore-with-fake-endpoints-models-for-testing.yaml -g java -c bin/java-petstore-okhttp-gson.json -o samples/client/petstore/java/okhttp-gson-parcelableModel --additional-properties hideGenerationTimestamp=true,parcelableModel=true $@"
rm -rf samples/client/petstore/java/okhttp-gson-parcelableModel/src/main
find samples/client/petstore/java/okhttp-gson-parcelableModel -maxdepth 1 -type f ! -name "README.md" -exec rm {} +

View File

@ -27,7 +27,7 @@ fi
# if you've executed sbt assembly previously it will use that instead.
export JAVA_OPTS="${JAVA_OPTS} -Xmx1024M -DloggerPath=conf/log4j.properties"
ags="generate -t modules/openapi-generator/src/main/resources/Java/libraries/okhttp-gson -i modules/openapi-generator/src/test/resources/2_0/petstore-with-fake-endpoints-models-for-testing.yaml -g java -c bin/java-petstore-okhttp-gson.json -o samples/client/petstore/java/okhttp-gson --additional-properties hideGenerationTimestamp=true $@"
ags="generate -t modules/openapi-generator/src/main/resources/Java -i modules/openapi-generator/src/test/resources/2_0/petstore-with-fake-endpoints-models-for-testing.yaml -g java -c bin/java-petstore-okhttp-gson.json -o samples/client/petstore/java/okhttp-gson --additional-properties hideGenerationTimestamp=true $@"
rm -rf samples/client/petstore/java/okhttp-gson/src/main
find samples/client/petstore/java/okhttp-gson -maxdepth 1 -type f ! -name "README.md" -exec rm {} +

View File

@ -28,7 +28,7 @@ fi
# if you've executed sbt assembly previously it will use that instead.
export JAVA_OPTS="${JAVA_OPTS} -Xmx1024M -DloggerPath=conf/log4j.properties"
args="generate -t modules/openapi-generator/src/main/resources/Java/libraries/rest-assured -i modules/openapi-generator/src/test/resources/2_0/petstore-with-fake-endpoints-models-for-testing.yaml -g java -c bin/java-petstore-rest-assured-jackson.json -o ${target_dir} --additional-properties hideGenerationTimestamp=true --additional-properties useBeanValidation=true --additional-properties performBeanValidation=true --additional-properties booleanGetterPrefix=is --additional-properties java8=true --additional-properties dateLibrary=java8 --additional-properties serializationLibrary=jackson $@"
args="generate -t modules/openapi-generator/src/main/resources/Java -i modules/openapi-generator/src/test/resources/2_0/petstore-with-fake-endpoints-models-for-testing.yaml -g java -c bin/java-petstore-rest-assured-jackson.json -o ${target_dir} --additional-properties hideGenerationTimestamp=true --additional-properties useBeanValidation=true --additional-properties performBeanValidation=true --additional-properties booleanGetterPrefix=is --additional-properties java8=true --additional-properties dateLibrary=java8 --additional-properties serializationLibrary=jackson $@"
echo "Removing ${target_dir}"
rm -rf "${target_dir}"

View File

@ -27,7 +27,7 @@ fi
# if you've executed sbt assembly previously it will use that instead.
export JAVA_OPTS="${JAVA_OPTS} -Xmx1024M -DloggerPath=conf/log4j.properties"
ags="generate -t modules/openapi-generator/src/main/resources/Java/libraries/rest-assured -i modules/openapi-generator/src/test/resources/2_0/petstore-with-fake-endpoints-models-for-testing.yaml -g java -c bin/java-petstore-rest-assured.json -o samples/client/petstore/java/rest-assured --additional-properties hideGenerationTimestamp=true --additional-properties useBeanValidation=true --additional-properties performBeanValidation=true --additional-properties booleanGetterPrefix=is $@"
ags="generate -t modules/openapi-generator/src/main/resources/Java -i modules/openapi-generator/src/test/resources/2_0/petstore-with-fake-endpoints-models-for-testing.yaml -g java -c bin/java-petstore-rest-assured.json -o samples/client/petstore/java/rest-assured --additional-properties hideGenerationTimestamp=true --additional-properties useBeanValidation=true --additional-properties performBeanValidation=true --additional-properties booleanGetterPrefix=is $@"
echo "Removing files and folders under samples/client/petstore/java/rest-assured/src/main"
rm -rf samples/client/petstore/java/rest-assured/src/main

View File

@ -27,7 +27,7 @@ fi
# if you've executed sbt assembly previously it will use that instead.
export JAVA_OPTS="${JAVA_OPTS} -Xmx1024M -DloggerPath=conf/log4j.properties"
ags="generate -t modules/openapi-generator/src/main/resources/Java/libraries/retrofit2 -i modules/openapi-generator/src/test/resources/2_0/petstore-with-fake-endpoints-models-for-testing.yaml -g java -c bin/java-petstore-retrofit2.json -o samples/client/petstore/java/retrofit2 --additional-properties hideGenerationTimestamp=true $@"
ags="generate -t modules/openapi-generator/src/main/resources/Java -i modules/openapi-generator/src/test/resources/2_0/petstore-with-fake-endpoints-models-for-testing.yaml -g java -c bin/java-petstore-retrofit2.json -o samples/client/petstore/java/retrofit2 --additional-properties hideGenerationTimestamp=true $@"
echo "Removing files and folders under samples/client/petstore/java/retrofit2/src/main"
rm -rf samples/client/petstore/java/retrofit2/src/main

View File

@ -27,7 +27,7 @@ fi
# if you've executed sbt assembly previously it will use that instead.
export JAVA_OPTS="${JAVA_OPTS} -Xmx1024M -DloggerPath=conf/log4j.properties"
ags="generate -t modules/openapi-generator/src/main/resources/Java/libraries/retrofit2 -i modules/openapi-generator/src/test/resources/2_0/petstore-with-fake-endpoints-models-for-testing.yaml -g java -c bin/java-petstore-retrofit2rx.json -o samples/client/petstore/java/retrofit2rx --additional-properties useRxJava=true,hideGenerationTimestamp=true $@"
ags="generate -t modules/openapi-generator/src/main/resources/Java -i modules/openapi-generator/src/test/resources/2_0/petstore-with-fake-endpoints-models-for-testing.yaml -g java -c bin/java-petstore-retrofit2rx.json -o samples/client/petstore/java/retrofit2rx --additional-properties useRxJava=true,hideGenerationTimestamp=true $@"
echo "Removing files and folders under samples/client/petstore/java/retrofit2rx/src/main"
rm -rf samples/client/petstore/java/retrofit2rx/src/main

View File

@ -27,7 +27,7 @@ fi
# if you've executed sbt assembly previously it will use that instead.
export JAVA_OPTS="${JAVA_OPTS} -Xmx1024M -DloggerPath=conf/log4j.properties"
ags="generate -t modules/openapi-generator/src/main/resources/Java/libraries/retrofit2 -i modules/openapi-generator/src/test/resources/2_0/petstore-with-fake-endpoints-models-for-testing.yaml -g java -c bin/java-petstore-retrofit2rx2.json -o samples/client/petstore/java/retrofit2rx2 --additional-properties useRxJava2=true,hideGenerationTimestamp=true $@"
ags="generate -t modules/openapi-generator/src/main/resources/Java -i modules/openapi-generator/src/test/resources/2_0/petstore-with-fake-endpoints-models-for-testing.yaml -g java -c bin/java-petstore-retrofit2rx2.json -o samples/client/petstore/java/retrofit2rx2 --additional-properties useRxJava2=true,hideGenerationTimestamp=true $@"
echo "Removing files and folders under samples/client/petstore/java/retrofit2rx2/src/main"
rm -rf samples/client/petstore/java/retrofit2rx2/src/main

View File

@ -27,7 +27,7 @@ fi
# if you've executed sbt assembly previously it will use that instead.
export JAVA_OPTS="${JAVA_OPTS} -Xmx1024M -DloggerPath=conf/log4j.properties"
ags="generate -t modules/openapi-generator/src/main/resources/Java/libraries/vertx -i modules/openapi-generator/src/test/resources/2_0/petstore-with-fake-endpoints-models-for-testing.yaml -g java -c bin/java-petstore-vertx.json -o samples/client/petstore/java/vertx --additional-properties hideGenerationTimestamp=true $@"
ags="generate -t modules/openapi-generator/src/main/resources/Java -i modules/openapi-generator/src/test/resources/2_0/petstore-with-fake-endpoints-models-for-testing.yaml -g java -c bin/java-petstore-vertx.json -o samples/client/petstore/java/vertx --additional-properties hideGenerationTimestamp=true $@"
echo "Removing files and folders under samples/client/petstore/java/vertx/src/main"
rm -rf samples/client/petstore/java/vertx/src/main

View File

@ -5,6 +5,6 @@ If Not Exist %executable% (
)
REM set JAVA_OPTS=%JAVA_OPTS% -Xmx1024M
set ags=generate -t modules\openapi-generator\src\main\resources\Java\libraries\feign -i modules\openapi-generator\src\test\resources\2_0\petstore-with-fake-endpoints-models-for-testing.yaml -g java -c bin\java-petstore-feign-10x.json -o samples\client\petstore\java\feign10x --additional-properties hideGenerationTimestamp=true,booleanGetterPrefix=is
set ags=generate -t modules\openapi-generator\src\main\resources\Java -i modules\openapi-generator\src\test\resources\2_0\petstore-with-fake-endpoints-models-for-testing.yaml -g java -c bin\java-petstore-feign-10x.json -o samples\client\petstore\java\feign10x --additional-properties hideGenerationTimestamp=true,booleanGetterPrefix=is
java %JAVA_OPTS% -jar %executable% %ags%

View File

@ -5,6 +5,6 @@ If Not Exist %executable% (
)
REM set JAVA_OPTS=%JAVA_OPTS% -Xmx1024M
set ags=generate -t modules\openapi-generator\src\main\resources\Java\libraries\google-api-client -i modules\openapi-generator\src\test\resources\2_0\petstore-with-fake-endpoints-models-for-testing.yaml -g java -c bin\java-petstore-google-api-client.json -o samples\client\petstore\java\google-api-client --additional-properties hideGenerationTimestamp=true
set ags=generate -t modules\openapi-generator\src\main\resources\Java -i modules\openapi-generator\src\test\resources\2_0\petstore-with-fake-endpoints-models-for-testing.yaml -g java -c bin\java-petstore-google-api-client.json -o samples\client\petstore\java\google-api-client --additional-properties hideGenerationTimestamp=true
java %JAVA_OPTS% -jar %executable% %ags%

View File

@ -5,6 +5,6 @@ If Not Exist %executable% (
)
REM set JAVA_OPTS=%JAVA_OPTS% -Xmx1024M
set ags=generate -t modules\openapi-generator\src\main\resources\Java\libraries\native -i modules\openapi-generator\src\test\resources\2_0\petstore-with-fake-endpoints-models-for-testing.yaml -g java -c bin\java-petstore-native.json -o samples\client\petstore\java\native --additional-properties hideGenerationTimestamp=true
set ags=generate -t modules\openapi-generator\src\main\resources\Java -i modules\openapi-generator\src\test\resources\2_0\petstore-with-fake-endpoints-models-for-testing.yaml -g java -c bin\java-petstore-native.json -o samples\client\petstore\java\native --additional-properties hideGenerationTimestamp=true
java %JAVA_OPTS% -jar %executable% %ags%

View File

@ -5,6 +5,6 @@ If Not Exist %executable% (
)
REM set JAVA_OPTS=%JAVA_OPTS% -Xmx1024M
set ags=generate --artifact-id petstore-okhttp-gson-parcelableModel -t modules\openapi-generator\src\main\resources\Java\libraries\okhttp-gson -i modules\openapi-generator\src\test\resources\2_0\petstore-with-fake-endpoints-models-for-testing.yaml -g java -c bin\java-petstore-okhttp-gson.json -o samples\client\petstore\java\okhttp-gson-parcelableModel --additional-properties hideGenerationTimestamp=true,parcelableModel=true
set ags=generate --artifact-id petstore-okhttp-gson-parcelableModel -t modules\openapi-generator\src\main\resources\Java -i modules\openapi-generator\src\test\resources\2_0\petstore-with-fake-endpoints-models-for-testing.yaml -g java -c bin\java-petstore-okhttp-gson.json -o samples\client\petstore\java\okhttp-gson-parcelableModel --additional-properties hideGenerationTimestamp=true,parcelableModel=true
java %JAVA_OPTS% -jar %executable% %ags%

View File

@ -5,6 +5,6 @@ If Not Exist %executable% (
)
REM set JAVA_OPTS=%JAVA_OPTS% -Xmx1024M
set ags=generate -t modules\openapi-generator\src\main\resources\Java\libraries\okhttp-gson -i modules\openapi-generator\src\test\resources\2_0\petstore-with-fake-endpoints-models-for-testing.yaml -g java -c bin\java-petstore-okhttp-gson.json -o samples\client\petstore\java\okhttp-gson --additional-properties hideGenerationTimestamp=true
set ags=generate -t modules\openapi-generator\src\main\resources\Java -i modules\openapi-generator\src\test\resources\2_0\petstore-with-fake-endpoints-models-for-testing.yaml -g java -c bin\java-petstore-okhttp-gson.json -o samples\client\petstore\java\okhttp-gson --additional-properties hideGenerationTimestamp=true
java %JAVA_OPTS% -jar %executable% %ags%

View File

@ -5,6 +5,6 @@ If Not Exist %executable% (
)
REM set JAVA_OPTS=%JAVA_OPTS% -Xmx1024M
set ags=generate -t modules\openapi-generator\src\main\resources\Java\libraries\rest-assured -i modules\openapi-generator\src\test\resources\2_0\petstore-with-fake-endpoints-models-for-testing.yaml -g java -c bin\java-petstore-rest-assured-jackson.json -o samples\client\petstore\java\rest-assured-jackson --additional-properties hideGenerationTimestamp=true,booleanGetterPrefix=is,java8=true,dateLibrary=java8,serializationLibrary=jackson,useBeanValidation=true,performBeanValidation=true,
set ags=generate -t modules\openapi-generator\src\main\resources\Java -i modules\openapi-generator\src\test\resources\2_0\petstore-with-fake-endpoints-models-for-testing.yaml -g java -c bin\java-petstore-rest-assured-jackson.json -o samples\client\petstore\java\rest-assured-jackson --additional-properties hideGenerationTimestamp=true,booleanGetterPrefix=is,java8=true,dateLibrary=java8,serializationLibrary=jackson,useBeanValidation=true,performBeanValidation=true,
java %JAVA_OPTS% -jar %executable% %ags%

View File

@ -5,6 +5,6 @@ If Not Exist %executable% (
)
REM set JAVA_OPTS=%JAVA_OPTS% -Xmx1024M
set ags=generate -t modules\openapi-generator\src\main\resources\Java\libraries\rest-assured -i modules\openapi-generator\src\test\resources\2_0\petstore-with-fake-endpoints-models-for-testing.yaml -g java -c bin\java-petstore-rest-assured.json -o samples\client\petstore\java\rest-assured --additional-properties hideGenerationTimestamp=true --additional-properties useBeanValidation=true --additional-properties performBeanValidation=true --additional-properties booleanGetterPrefix=is
set ags=generate -t modules\openapi-generator\src\main\resources\Java -i modules\openapi-generator\src\test\resources\2_0\petstore-with-fake-endpoints-models-for-testing.yaml -g java -c bin\java-petstore-rest-assured.json -o samples\client\petstore\java\rest-assured --additional-properties hideGenerationTimestamp=true --additional-properties useBeanValidation=true --additional-properties performBeanValidation=true --additional-properties booleanGetterPrefix=is
java %JAVA_OPTS% -jar %executable% %ags%

View File

@ -5,6 +5,6 @@ If Not Exist %executable% (
)
REM set JAVA_OPTS=%JAVA_OPTS% -Xmx1024M
set ags=generate -t modules\openapi-generator\src\main\resources\Java\libraries\retrofit2 -i modules\openapi-generator\src\test\resources\2_0\petstore-with-fake-endpoints-models-for-testing.yaml -g java -c bin\java-petstore-retrofit2.json -o samples\client\petstore\java\retrofit2 --additional-properties hideGenerationTimestamp=true
set ags=generate -t modules\openapi-generator\src\main\resources\Java -i modules\openapi-generator\src\test\resources\2_0\petstore-with-fake-endpoints-models-for-testing.yaml -g java -c bin\java-petstore-retrofit2.json -o samples\client\petstore\java\retrofit2 --additional-properties hideGenerationTimestamp=true
java %JAVA_OPTS% -jar %executable% %ags%

View File

@ -5,6 +5,6 @@ If Not Exist %executable% (
)
REM set JAVA_OPTS=%JAVA_OPTS% -Xmx1024M
set ags=generate -t modules\openapi-generator\src\main\resources\Java\libraries\retrofit2 -i modules\openapi-generator\src\test\resources\2_0\petstore-with-fake-endpoints-models-for-testing.yaml -g java -c bin\java-petstore-retrofit2rx.json -o samples\client\petstore\java\retrofit2rx --additional-properties useRxJava=true,hideGenerationTimestamp=true
set ags=generate -t modules\openapi-generator\src\main\resources\Java -i modules\openapi-generator\src\test\resources\2_0\petstore-with-fake-endpoints-models-for-testing.yaml -g java -c bin\java-petstore-retrofit2rx.json -o samples\client\petstore\java\retrofit2rx --additional-properties useRxJava=true,hideGenerationTimestamp=true
java %JAVA_OPTS% -jar %executable% %ags%

View File

@ -5,6 +5,6 @@ If Not Exist %executable% (
)
REM set JAVA_OPTS=%JAVA_OPTS% -Xmx1024M
set ags=generate -t modules\openapi-generator\src\main\resources\Java\libraries\retrofit2 -i modules\openapi-generator\src\test\resources\2_0\petstore-with-fake-endpoints-models-for-testing.yaml -g java -c bin\java-petstore-retrofit2rx2.json -o samples\client\petstore\java\retrofit2rx2 --additional-properties useRxJava2=true,hideGenerationTimestamp=true
set ags=generate -t modules\openapi-generator\src\main\resources\Java -i modules\openapi-generator\src\test\resources\2_0\petstore-with-fake-endpoints-models-for-testing.yaml -g java -c bin\java-petstore-retrofit2rx2.json -o samples\client\petstore\java\retrofit2rx2 --additional-properties useRxJava2=true,hideGenerationTimestamp=true
java %JAVA_OPTS% -jar %executable% %ags%

View File

@ -5,6 +5,6 @@ If Not Exist %executable% (
)
REM set JAVA_OPTS=%JAVA_OPTS% -Xmx1024M
set ags=generate -t modules\openapi-generator\src\main\resources\Java\libraries\vertx -i modules\openapi-generator\src\test\resources\2_0\petstore-with-fake-endpoints-models-for-testing.yaml -g java -c bin\java-petstore-vertx.json -o samples\client\petstore\java\vertx --additional-properties hideGenerationTimestamp=true
set ags=generate -t modules\openapi-generator\src\main\resources\Java -i modules\openapi-generator\src\test\resources\2_0\petstore-with-fake-endpoints-models-for-testing.yaml -g java -c bin\java-petstore-vertx.json -o samples\client\petstore\java\vertx --additional-properties hideGenerationTimestamp=true
java %JAVA_OPTS% -jar %executable% %ags%

View File

@ -30,6 +30,11 @@ import org.apache.commons.io.FileUtils;
import org.openapitools.codegen.CodegenConfig;
import org.openapitools.codegen.DefaultGenerator;
import org.openapitools.codegen.SupportingFile;
import org.openapitools.codegen.TemplateManager;
import org.openapitools.codegen.api.TemplatePathLocator;
import org.openapitools.codegen.templating.MustacheEngineAdapter;
import org.openapitools.codegen.templating.TemplateManagerOptions;
import org.openapitools.codegen.templating.CommonTemplateContentLocator;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@ -136,52 +141,38 @@ public class Meta extends OpenApiGeneratorCommand {
*/
private static Converter<SupportingFile, File> processFiles(final File targetDir,
final Map<String, Object> data) {
return new Converter<SupportingFile, File>() {
private DefaultGenerator generator = new DefaultGenerator();
return support -> {
try {
File destinationFolder =
new File(new File(targetDir.getAbsolutePath()), support.folder);
File outputFile = new File(destinationFolder, support.destinationFilename);
@Override
public File convert(SupportingFile support) {
try {
File destinationFolder =
new File(new File(targetDir.getAbsolutePath()), support.folder);
File outputFile = new File(destinationFolder, support.destinationFilename);
TemplateManager templateProcessor = new TemplateManager(
new TemplateManagerOptions(false, false),
new MustacheEngineAdapter(),
new TemplatePathLocator[]{ new CommonTemplateContentLocator("codegen") }
);
String template =
generator.readTemplate(new File(TEMPLATE_DIR_CLASSPATH,
support.templateFile).getPath());
String formatted = template;
String template = templateProcessor.readTemplate(new File(TEMPLATE_DIR_CLASSPATH, support.templateFile).getPath());
if (support.templateFile.endsWith(MUSTACHE_EXTENSION)) {
LOGGER.info("writing file to {}", outputFile.getAbsolutePath());
formatted =
Mustache.compiler().withLoader(loader(generator)).defaultValue("")
.compile(template).execute(data);
} else {
LOGGER.info("copying file to {}", outputFile.getAbsolutePath());
}
String formatted = template;
FileUtils.writeStringToFile(outputFile, formatted, StandardCharsets.UTF_8);
return outputFile;
Mustache.TemplateLoader loader = name -> templateProcessor.getTemplateReader(name.concat(MUSTACHE_EXTENSION));
} catch (IOException e) {
throw new RuntimeException("Can't generate project", e);
if (support.templateFile.endsWith(MUSTACHE_EXTENSION)) {
LOGGER.info("writing file to {}", outputFile.getAbsolutePath());
formatted =
Mustache.compiler().withLoader(loader).defaultValue("")
.compile(template).execute(data);
} else {
LOGGER.info("copying file to {}", outputFile.getAbsolutePath());
}
}
};
}
/**
* Creates mustache loader for template using classpath loader
*
* @param generator - class with reader getter
* @return loader for template
*/
private static Mustache.TemplateLoader loader(final DefaultGenerator generator) {
return new Mustache.TemplateLoader() {
@Override
public Reader getTemplate(String name) {
return generator.getTemplateReader(TEMPLATE_DIR_CLASSPATH + File.separator
+ name.concat(MUSTACHE_EXTENSION));
FileUtils.writeStringToFile(outputFile, formatted, StandardCharsets.UTF_8);
return outputFile;
} catch (IOException e) {
throw new RuntimeException("Can't generate project", e);
}
};
}

View File

@ -0,0 +1,14 @@
package org.openapitools.codegen.api;
/**
* Provides means for searching for "actual" template location based on relative template file.
*/
public interface TemplatePathLocator {
/**
* Get the full path to a relative template file.
*
* @param relativeTemplateFile Template file
* @return String Full template file path
*/
String getFullTemplatePath(String relativeTemplateFile);
}

View File

@ -0,0 +1,57 @@
package org.openapitools.codegen.api;
import java.io.File;
import java.io.IOException;
import java.nio.file.Path;
import java.util.Map;
/**
* Interface for abstractions around writing templated data to a file.
*/
public interface TemplateProcessor {
/**
* Writes data to a compiled template
*
* @param data Input data
* @param template Input template location
* @param target The targeted file output location
*
* @return The actual file
* @throws IOException If file cannot be written.
*/
File write(Map<String, Object> data, String template, File target) throws IOException;
/**
* Write bytes to a file
*
* @param filename The name of file to write
* @param contents The contents bytes. Typically this is a UTF-8 formatted string.
* @return File representing the written file.
* @throws IOException If file cannot be written.
*/
File writeToFile(String filename, byte[] contents) throws IOException;
/**
* Allow a caller to mark a path as ignored with accompanying reason
*
* @param path The ignored path
* @param context The reason for ignoring this path
*/
void ignore(Path path, String context);
/**
* Allow a caller to mark a path as skipped with accompanying reason
*
* @param path The skipped path
* @param context The reason for skipping this path
*/
void skip(Path path, String context);
/**
* Allow a caller to mark a path having errored during processing with accompanying reason
*
* @param path The path which has caused an error
* @param context The reason for the error
*/
default void error(Path path, String context) { };
}

View File

@ -36,18 +36,6 @@ public interface TemplatingEngineAdapter {
*/
String getIdentifier();
/**
* Compiles a template into a string
*
* @param generator From where we can fetch the templates content (e.g. an instance of DefaultGenerator)
* @param bundle The map of values to pass to the template
* @param templateFile The name of the template (e.g. model.mustache )
* @return the processed template result
* @throws IOException an error ocurred in the template processing
*/
String compileTemplate(TemplatingGenerator generator, Map<String, Object> bundle,
String templateFile) throws IOException;
/**
* During generation, if a supporting file has a file extension that is
* inside that array, then it is considered a templated supporting file
@ -57,6 +45,18 @@ public interface TemplatingEngineAdapter {
*/
String[] getFileExtensions();
/**
* Compiles a template into a string
*
* @param executor From where we can fetch the templates content (e.g. an instance of DefaultGenerator)
* @param bundle The map of values to pass to the template
* @param templateFile The name of the template (e.g. model.mustache )
* @return the processed template result
* @throws IOException an error ocurred in the template processing
*/
String compileTemplate(TemplatingExecutor executor, Map<String, Object> bundle,
String templateFile) throws IOException;
/**
* Determines whether the template file with supported extensions exists. This may be on the filesystem,
* external filesystem, or classpath (implementation is up to TemplatingGenerator).
@ -65,7 +65,7 @@ public interface TemplatingEngineAdapter {
* @param templateFile The original target filename
* @return True if the template is available in the template search path, false if it can not be found
*/
default boolean templateExists(TemplatingGenerator generator, String templateFile) {
default boolean templateExists(TemplatingExecutor generator, String templateFile) {
return Arrays.stream(getFileExtensions()).anyMatch(ext -> {
int idx = templateFile.lastIndexOf(".");
String baseName;

View File

@ -0,0 +1,26 @@
package org.openapitools.codegen.api;
import java.nio.file.Path;
/**
* interface to the full template content
* implementers might take into account the -t cli option,
* look in the resources for a generator specific template, etc
*/
public interface TemplatingExecutor {
/**
* returns the template content by name
*
* @param name the template name (e.g. model.mustache)
* @return the contents of that template
*/
String getFullTemplateContents(String name);
/**
* Returns the path of a template, allowing access to the template where consuming literal contents aren't desirable or possible.
*
* @param name the template name (e.g. model.mustache)
* @return The {@link Path} to the template
*/
Path getFullTemplatePath(String name);
}

View File

@ -16,28 +16,15 @@
package org.openapitools.codegen.api;
import java.nio.file.Path;
// TODO: 6.0 Remove
/**
* interface to the full template content
* implementers might take into account the -t cli option,
* look in the resources for a language specific template, etc
*
* @deprecated as of 5.0, replaced by {@link TemplatingExecutor}.
*/
public interface TemplatingGenerator {
@Deprecated()
public interface TemplatingGenerator extends TemplatingExecutor {
/**
* returns the template content by name
*
* @param name the template name (e.g. model.mustache)
* @return the contents of that template
*/
String getFullTemplateContents(String name);
/**
* Returns the path of a template, allowing access to the template where consuming literal contents aren't desirable or possible.
*
* @param name the template name (e.g. model.mustache)
* @return The {@link Path} to the template
*/
Path getFullTemplatePath(String name);
}

View File

@ -24,10 +24,12 @@ import org.gradle.api.tasks.TaskAction
import org.gradle.internal.logging.text.StyledTextOutput
import org.gradle.internal.logging.text.StyledTextOutputFactory
import org.gradle.kotlin.dsl.property
import org.openapitools.codegen.CodegenConfig
import org.openapitools.codegen.CodegenConstants
import org.openapitools.codegen.DefaultGenerator
import org.openapitools.codegen.SupportingFile
import org.openapitools.codegen.*
import org.openapitools.codegen.api.TemplatePathLocator
import org.openapitools.codegen.templating.CommonTemplateContentLocator
import org.openapitools.codegen.templating.GeneratorTemplateContentLocator
import org.openapitools.codegen.templating.MustacheEngineAdapter
import org.openapitools.codegen.templating.TemplateManagerOptions
import java.io.File
import java.io.IOException
import java.nio.charset.Charset
@ -83,19 +85,28 @@ open class MetaTask : DefaultTask() {
"fullyQualifiedGeneratorClass" to "${packageName.get()}.$klass",
"openapiGeneratorVersion" to currentVersion)
val generator = DefaultGenerator()
supportingFiles.map {
try {
val destinationFolder = File(File(dir.absolutePath), it.folder)
destinationFolder.mkdirs()
val outputFile = File(destinationFolder, it.destinationFilename)
val template = generator.readTemplate(File("codegen", it.templateFile).path)
val templateProcessor = TemplateManager(
TemplateManagerOptions(false, false),
MustacheEngineAdapter(),
arrayOf(CommonTemplateContentLocator("codegen"))
)
val template = templateProcessor.getFullTemplateContents(it.templateFile)
var formatted = template
val loader = Mustache.TemplateLoader { name ->
templateProcessor.getTemplateReader("$name.mustache")
}
if (it.templateFile.endsWith(".mustache")) {
formatted = Mustache.compiler()
.withLoader(loader(generator))
.withLoader(loader)
.defaultValue("")
.compile(template).execute(data)
}
@ -115,12 +126,6 @@ open class MetaTask : DefaultTask() {
out.formatln("Created generator %s", klass)
}
private fun loader(generator: DefaultGenerator): Mustache.TemplateLoader {
return Mustache.TemplateLoader { name ->
generator.getTemplateReader("codegen${File.separator}$name.mustache")
}
}
private fun String.titleCasedTextOnly(): String =
this.split(Regex("[^a-zA-Z0-9]")).joinToString(separator = "", transform = String::capitalize)

View File

@ -152,13 +152,14 @@ class GenerateTaskDslTest : TestBase() {
// Act
val result = GradleRunner.create()
.withProjectDir(temp)
.withArguments("openApiGenerate")
.withArguments("openApiGenerate", "--stacktrace")
.withPluginClasspath()
.buildAndFail()
// Assert
// rather than write out full handlebars generator templates, we'll just test that the configurator has set handlebars as the engine.
assertTrue(result.output.contains("kotlin-client/model.handlebars (No such file or directory)"), "Build should have attempted to use handlebars.")
assertTrue(result.output.contains("HandlebarsException"), "Stack should expose an exception for missing templates.")
assertTrue(result.output.contains("handlebars"), "Build should have attempted to use handlebars.")
assertEquals(TaskOutcome.FAILED, result.task(":openApiGenerate")?.outcome,
"Expected a failed run, but found ${result.task(":openApiGenerate")?.outcome}")
}

View File

@ -29,7 +29,7 @@ class MetaTaskDslTest : TestBase() {
// Act
val result = GradleRunner.create()
.withProjectDir(temp)
.withArguments("openApiMeta")
.withArguments("openApiMeta", "--stacktrace")
.withPluginClasspath()
.build()

View File

@ -1,213 +0,0 @@
/*
* Copyright 2018 OpenAPI-Generator Contributors (https://openapi-generator.tech)
* Copyright 2018 SmartBear Software
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.openapitools.codegen;
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import java.nio.file.StandardCopyOption;
import java.util.Arrays;
import org.apache.commons.lang3.StringUtils;
import org.openapitools.codegen.api.TemplatingGenerator;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.io.*;
import java.nio.file.Paths;
import java.util.HashMap;
import java.util.Map;
import java.util.Scanner;
import java.util.regex.Pattern;
public abstract class AbstractGenerator implements TemplatingGenerator {
private static final Logger LOGGER = LoggerFactory.getLogger(AbstractGenerator.class);
protected boolean dryRun = false;
protected Map<String, DryRunStatus> dryRunStatusMap = new HashMap<>();
/**
* Is the minimal-file-update option enabled?
*
* @return Option value
*/
public abstract boolean getEnableMinimalUpdate();
/**
* Write String to a file, formatting as UTF-8
*
* @param filename The name of file to write
* @param contents The contents string.
* @return File representing the written file.
* @throws IOException If file cannot be written.
*/
public File writeToFile(String filename, String contents) throws IOException {
return writeToFile(filename, contents.getBytes(StandardCharsets.UTF_8));
}
/**
* Write bytes to a file
*
* @param filename The name of file to write
* @param contents The contents bytes. Typically, this is a UTF-8 formatted string.
* @return File representing the written file.
* @throws IOException If file cannot be written.
*/
@SuppressWarnings("static-method")
public File writeToFile(String filename, byte[] contents) throws IOException {
if (getEnableMinimalUpdate()) {
String tempFilename = filename + ".tmp";
// Use Paths.get here to normalize path (for Windows file separator, space escaping on Linux/Mac, etc)
File outputFile = Paths.get(filename).toFile();
File tempFile = null;
try {
tempFile = writeToFileRaw(tempFilename, contents);
if (!filesEqual(tempFile, outputFile)) {
LOGGER.info("writing file " + filename);
Files.move(tempFile.toPath(), outputFile.toPath(), StandardCopyOption.REPLACE_EXISTING);
tempFile = null;
} else {
LOGGER.info("skipping unchanged file " + filename);
}
} finally {
if (tempFile != null && tempFile.exists()) {
try {
tempFile.delete();
} catch (Exception ex) {
LOGGER.error("Error removing temporary file " + tempFile, ex);
}
}
}
return outputFile;
} else {
LOGGER.info("writing file " + filename);
return writeToFileRaw(filename, contents);
}
}
private boolean filesEqual(File file1, File file2) throws IOException {
return file1.exists() && file2.exists() && Arrays.equals(Files.readAllBytes(file1.toPath()), Files.readAllBytes(file2.toPath()));
}
private File writeToFileRaw(String filename, byte[] contents) throws IOException {
// Use Paths.get here to normalize path (for Windows file separator, space escaping on Linux/Mac, etc)
File output = Paths.get(filename).toFile();
if (output.getParent() != null && !new File(output.getParent()).exists()) {
File parent = Paths.get(output.getParent()).toFile();
parent.mkdirs();
}
Files.write(output.toPath(), contents);
return output;
}
public String readTemplate(String name) {
try {
Reader reader = getTemplateReader(name);
if (reader == null) {
throw new RuntimeException("no file found");
}
Scanner s = new Scanner(reader).useDelimiter("\\A");
return s.hasNext() ? s.next() : "";
} catch (Exception e) {
LOGGER.error(e.getMessage());
}
throw new RuntimeException("can't load template " + name);
}
@SuppressWarnings("squid:S2095")
// ignored rule as used in the CLI and it's required to return a reader
public Reader getTemplateReader(String name) {
InputStream is = null;
try {
is = this.getClass().getClassLoader().getResourceAsStream(getCPResourcePath(name));
if (is == null) {
is = new FileInputStream(new File(name)); // May throw but never return a null value
}
return new InputStreamReader(is, "UTF-8");
} catch (FileNotFoundException | UnsupportedEncodingException e) {
LOGGER.error(e.getMessage());
throw new RuntimeException("can't load template " + name);
}
}
private String buildLibraryFilePath(String dir, String library, String file) {
return dir + File.separator + "libraries" + File.separator + library + File.separator + file;
}
/**
* Get the template file path with template dir prepended, and use the
* library template if exists.
*
* @param config Codegen config
* @param templateFile Template file
* @return String Full template file path
*/
public String getFullTemplateFile(CodegenConfig config, String templateFile) {
//1st the code will check if there's a <template folder>/libraries/<library> folder containing the file
//2nd it will check for the file in the specified <template folder> folder
//3rd it will check if there's an <embedded template>/libraries/<library> folder containing the file
//4th and last it will assume the file is in <embedded template> folder.
//check the supplied template library folder for the file
final String library = config.getLibrary();
if (StringUtils.isNotEmpty(library)) {
//look for the file in the library subfolder of the supplied template
final String libTemplateFile = buildLibraryFilePath(config.templateDir(), library, templateFile);
if (new File(libTemplateFile).exists() || this.getClass().getClassLoader().getResource(libTemplateFile) != null) {
return libTemplateFile;
}
}
//check the supplied template main folder for the file
final String template = config.templateDir() + File.separator + templateFile;
if (new File(template).exists() || this.getClass().getClassLoader().getResource(template) != null) {
return template;
}
//try the embedded template library folder next
if (StringUtils.isNotEmpty(library)) {
final String embeddedLibTemplateFile = buildLibraryFilePath(config.embeddedTemplateDir(), library, templateFile);
if (embeddedTemplateExists(embeddedLibTemplateFile)) {
// Fall back to the template file embedded/packaged in the JAR file library folder...
return embeddedLibTemplateFile;
}
}
// Fall back to the template file embedded/packaged in the JAR file...
return config.embeddedTemplateDir() + File.separator + templateFile;
}
public String readResourceContents(String resourceFilePath) {
StringBuilder sb = new StringBuilder();
Scanner scanner = new Scanner(this.getClass().getResourceAsStream(getCPResourcePath(resourceFilePath)), "UTF-8");
while (scanner.hasNextLine()) {
String line = scanner.nextLine();
sb.append(line).append('\n');
}
return sb.toString();
}
public boolean embeddedTemplateExists(String name) {
return this.getClass().getClassLoader().getResource(getCPResourcePath(name)) != null;
}
@SuppressWarnings("static-method")
public String getCPResourcePath(String name) {
if (!"/".equals(File.separator)) {
return name.replaceAll(Pattern.quote(File.separator), "/");
}
return name;
}
}

View File

@ -247,8 +247,6 @@ public interface CodegenConfig {
String getDocExtension();
String getCommonTemplateDir();
void setIgnoreFilePathOverride(String ignoreFileOverride);
String getIgnoreFilePathOverride();

View File

@ -164,7 +164,6 @@ public class DefaultCodegen implements CodegenConfig {
protected Map<String, String> reservedWordsMappings = new HashMap<String, String>();
protected String templateDir;
protected String embeddedTemplateDir;
protected String commonTemplateDir = "_common";
protected Map<String, Object> additionalProperties = new HashMap<String, Object>();
protected Map<String, String> serverVariables = new HashMap<String, String>();
protected Map<String, Object> vendorExtensions = new HashMap<String, Object>();
@ -982,14 +981,6 @@ public class DefaultCodegen implements CodegenConfig {
}
}
public String getCommonTemplateDir() {
return this.commonTemplateDir;
}
public void setCommonTemplateDir(String commonTemplateDir) {
this.commonTemplateDir = commonTemplateDir;
}
public Map<String, String> apiDocTemplateFiles() {
return apiDocTemplateFiles;
}
@ -1470,12 +1461,6 @@ public class DefaultCodegen implements CodegenConfig {
importMapping.put("LocalDate", "org.joda.time.*");
importMapping.put("LocalTime", "org.joda.time.*");
// we've used the .openapi-generator-ignore approach as
// suppportingFiles can be cleared by code generator that extends
// the default codegen, leaving the commented code below for
// future reference
//supportingFiles.add(new GlobalSupportingFile("LICENSE", "LICENSE"));
cliOptions.add(CliOption.newBoolean(CodegenConstants.SORT_PARAMS_BY_REQUIRED_FLAG,
CodegenConstants.SORT_PARAMS_BY_REQUIRED_FLAG_DESC).defaultValue(Boolean.TRUE.toString()));
cliOptions.add(CliOption.newBoolean(CodegenConstants.SORT_MODEL_PROPERTIES_BY_REQUIRED_FLAG,

View File

@ -29,10 +29,11 @@ import io.swagger.v3.oas.models.media.Schema;
import io.swagger.v3.oas.models.parameters.Parameter;
import io.swagger.v3.oas.models.security.*;
import io.swagger.v3.oas.models.tags.Tag;
import org.apache.commons.io.IOUtils;
import org.apache.commons.io.comparator.PathFileComparator;
import org.apache.commons.lang3.ObjectUtils;
import org.apache.commons.lang3.StringUtils;
import org.openapitools.codegen.api.TemplatePathLocator;
import org.openapitools.codegen.api.TemplateProcessor;
import org.openapitools.codegen.config.GlobalSettings;
import org.openapitools.codegen.api.TemplatingEngineAdapter;
import org.openapitools.codegen.ignore.CodegenIgnoreProcessor;
@ -40,7 +41,10 @@ import org.openapitools.codegen.languages.PythonClientExperimentalCodegen;
import org.openapitools.codegen.meta.GeneratorMetadata;
import org.openapitools.codegen.meta.Stability;
import org.openapitools.codegen.serializer.SerializerUtils;
import org.openapitools.codegen.templating.CommonTemplateContentLocator;
import org.openapitools.codegen.templating.GeneratorTemplateContentLocator;
import org.openapitools.codegen.templating.MustacheEngineAdapter;
import org.openapitools.codegen.templating.TemplateManagerOptions;
import org.openapitools.codegen.utils.ImplementationVersion;
import org.openapitools.codegen.utils.ModelUtils;
import org.openapitools.codegen.utils.ProcessUtils;
@ -58,14 +62,14 @@ import java.util.*;
import static org.openapitools.codegen.utils.OnceLogger.once;
@SuppressWarnings("rawtypes")
public class DefaultGenerator extends AbstractGenerator implements Generator {
public class DefaultGenerator implements Generator {
private static final String METADATA_DIR = ".openapi-generator";
protected final Logger LOGGER = LoggerFactory.getLogger(DefaultGenerator.class);
private final boolean dryRun;
protected CodegenConfig config;
protected ClientOptInput opts;
protected OpenAPI openAPI;
protected CodegenIgnoreProcessor ignoreProcessor;
protected TemplatingEngineAdapter templatingEngine;
private Boolean generateApis = null;
private Boolean generateModels = null;
private Boolean generateSupportingFiles = null;
@ -78,9 +82,11 @@ public class DefaultGenerator extends AbstractGenerator implements Generator {
private String basePathWithoutHost;
private String contextPath;
private Map<String, String> generatorPropertyDefaults = new HashMap<>();
protected TemplateProcessor templateProcessor = null;
public DefaultGenerator() {
this(false);
}
public DefaultGenerator(Boolean dryRun) {
@ -88,18 +94,33 @@ public class DefaultGenerator extends AbstractGenerator implements Generator {
LOGGER.info("Generating with dryRun={}", this.dryRun);
}
@Override
public boolean getEnableMinimalUpdate() {
return config.isEnableMinimalUpdate();
}
@SuppressWarnings("deprecation")
@Override
public Generator opts(ClientOptInput opts) {
this.opts = opts;
this.openAPI = opts.getOpenAPI();
this.config = opts.getConfig();
this.templatingEngine = this.config.getTemplatingEngine();
TemplateManagerOptions templateManagerOptions = new TemplateManagerOptions(this.config.isEnableMinimalUpdate(),this.config.isSkipOverwrite());
if (this.dryRun) {
this.templateProcessor = new DryRunTemplateManager(templateManagerOptions);
} else {
TemplatingEngineAdapter templatingEngine = this.config.getTemplatingEngine();
if (templatingEngine instanceof MustacheEngineAdapter) {
MustacheEngineAdapter mustacheEngineAdapter = (MustacheEngineAdapter) templatingEngine;
mustacheEngineAdapter.setCompiler(this.config.processCompiler(mustacheEngineAdapter.getCompiler()));
}
TemplatePathLocator commonTemplateLocator = new CommonTemplateContentLocator();
TemplatePathLocator generatorTemplateLocator = new GeneratorTemplateContentLocator(this.config);
this.templateProcessor = new TemplateManager(
templateManagerOptions,
templatingEngine,
new TemplatePathLocator[]{generatorTemplateLocator, commonTemplateLocator}
);
}
String ignoreFileLocation = this.config.getIgnoreFilePathOverride();
if (ignoreFileLocation != null) {
@ -118,11 +139,14 @@ public class DefaultGenerator extends AbstractGenerator implements Generator {
return this;
}
private void configPostProcessMustacheCompiler() {
if (this.templatingEngine instanceof MustacheEngineAdapter) {
MustacheEngineAdapter mustacheEngineAdapter = (MustacheEngineAdapter) this.templatingEngine;
mustacheEngineAdapter.setCompiler(this.config.processCompiler(mustacheEngineAdapter.getCompiler()));
}
/**
* Retrieves an instance to the configured template processor, available after user-defined options are
* applied via {@link DefaultGenerator#opts(ClientOptInput)}.
*
* @return A configured {@link TemplateProcessor}, or null.
*/
public TemplateProcessor getTemplateProcessor() {
return templateProcessor;
}
/**
@ -304,32 +328,21 @@ public class DefaultGenerator extends AbstractGenerator implements Generator {
if (generateModelTests) {
// do not overwrite test file that already exists (regardless of config's skipOverwrite setting)
if (new File(filename).exists()) {
LOGGER.info("File exists. Skipped overwriting {}", filename);
if (dryRun) {
dryRunStatusMap.put(filename,
new DryRunStatus(
java.nio.file.Paths.get(filename),
DryRunStatus.State.SkippedOverwrite,
"Test files never overwrite an existing file of the same name."
));
}
continue;
}
File written = processTemplateToFile(models, templateName, filename);
if (written != null) {
files.add(written);
if (config.isEnablePostProcessFile() && !dryRun) {
config.postProcessFile(written, "model-test");
File modelTestFile = new File(filename);
if (modelTestFile.exists()) {
this.templateProcessor.skip(modelTestFile.toPath(), "Test files never overwrite an existing file of the same name.");
} else {
File written = processTemplateToFile(models, templateName, filename, generateModelTests, CodegenConstants.MODEL_TESTS);
if (written != null) {
files.add(written);
if (config.isEnablePostProcessFile() && !dryRun) {
config.postProcessFile(written, "model-test");
}
}
}
} else if (dryRun) {
dryRunStatusMap.put(filename,
new DryRunStatus(
java.nio.file.Paths.get(filename),
DryRunStatus.State.Skipped,
"Skipped by modelTests option supplied by user."
));
Path skippedPath = java.nio.file.Paths.get(filename);
this.templateProcessor.skip(skippedPath, "Skipped by modelTests option supplied by user.");
}
}
}
@ -340,28 +353,12 @@ public class DefaultGenerator extends AbstractGenerator implements Generator {
String suffix = docExtension != null ? docExtension : config.modelDocTemplateFiles().get(templateName);
String filename = config.modelDocFileFolder() + File.separator + config.toModelDocFilename(modelName) + suffix;
if (generateModelDocumentation) {
if (!config.shouldOverwrite(filename)) {
LOGGER.info("Skipped overwriting {}", filename);
if (dryRun) {
dryRunStatusMap.put(filename, new DryRunStatus(java.nio.file.Paths.get(filename), DryRunStatus.State.SkippedOverwrite));
}
continue;
File written = processTemplateToFile(models, templateName, filename, generateModelDocumentation, CodegenConstants.MODEL_DOCS);
if (written != null) {
files.add(written);
if (config.isEnablePostProcessFile() && !dryRun) {
config.postProcessFile(written, "model-doc");
}
File written = processTemplateToFile(models, templateName, filename);
if (written != null) {
files.add(written);
if (config.isEnablePostProcessFile() && !dryRun) {
config.postProcessFile(written, "model-doc");
}
}
} else if (dryRun) {
dryRunStatusMap.put(filename,
new DryRunStatus(
java.nio.file.Paths.get(filename),
DryRunStatus.State.Skipped,
"Skipped by modelDocs option supplied by user."
));
}
}
}
@ -374,24 +371,12 @@ public class DefaultGenerator extends AbstractGenerator implements Generator {
private void generateModel(List<File> files, Map<String, Object> models, String modelName) throws IOException {
for (String templateName : config.modelTemplateFiles().keySet()) {
String filename = getModelFilenameByTemplate(modelName, templateName);
if (!config.shouldOverwrite(filename)) {
LOGGER.info("Skipped overwriting {}", filename);
if (dryRun) {
dryRunStatusMap.put(filename, new DryRunStatus(
java.nio.file.Paths.get(filename),
DryRunStatus.State.SkippedOverwrite
));
}
continue;
}
File written = processTemplateToFile(models, templateName, filename);
File written = processTemplateToFile(models, templateName, filename, generateModels, CodegenConstants.MODELS);
if (written != null) {
files.add(written);
if (config.isEnablePostProcessFile() && !dryRun) {
config.postProcessFile(written, "model");
}
} else {
LOGGER.warn("Unknown issue writing {}", filename);
}
}
}
@ -441,16 +426,12 @@ public class DefaultGenerator extends AbstractGenerator implements Generator {
//don't generate models that have an import mapping
if (config.importMapping().containsKey(name)) {
LOGGER.debug("Model {} not imported due to import mapping", name);
if (dryRun) {
for (String templateName : config.modelTemplateFiles().keySet()) {
// HACK: Because this returns early, could lead to some invalid model reporting.
for (String templateName : config.modelTemplateFiles().keySet()) {
String filename = getModelFilenameByTemplate(name, templateName);
dryRunStatusMap.put(filename, new DryRunStatus(
java.nio.file.Paths.get(filename),
DryRunStatus.State.Skipped,
"Skipped prior to model processing due to import mapping conflict (either by user or by generator)."
));
}
String filename = getModelFilenameByTemplate(name, templateName);
Path path = java.nio.file.Paths.get(filename);
this.templateProcessor.skip(path,"Skipped prior to model processing due to import mapping conflict (either by user or by generator)." );
}
continue;
}
@ -636,17 +617,7 @@ public class DefaultGenerator extends AbstractGenerator implements Generator {
for (String templateName : config.apiTemplateFiles().keySet()) {
String filename = config.apiFilename(templateName, tag);
File apiFile = new File(filename);
if (!config.shouldOverwrite(filename) && apiFile.exists()) {
LOGGER.info("Skipped overwriting {}", filename);
if (dryRun) {
DryRunStatus status = new DryRunStatus(apiFile.toPath(), DryRunStatus.State.SkippedOverwrite);
dryRunStatusMap.put(filename, status);
}
continue;
}
File written = processTemplateToFile(operation, templateName, filename);
File written = processTemplateToFile(operation, templateName, filename, generateApis, CodegenConstants.APIS);
if (written != null) {
files.add(written);
if (config.isEnablePostProcessFile() && !dryRun) {
@ -659,58 +630,29 @@ public class DefaultGenerator extends AbstractGenerator implements Generator {
for (String templateName : config.apiTestTemplateFiles().keySet()) {
String filename = config.apiTestFilename(templateName, tag);
File apiTestFile = new File(filename);
if (generateApiTests) {
// do not overwrite test file that already exists
if (apiTestFile.exists()) {
LOGGER.info("File exists. Skipped overwriting {}", filename);
if (dryRun) {
dryRunStatusMap.put(filename, new DryRunStatus(apiTestFile.toPath(), DryRunStatus.State.SkippedOverwrite));
}
continue;
}
File written = processTemplateToFile(operation, templateName, filename);
// do not overwrite test file that already exists
if (apiTestFile.exists()) {
this.templateProcessor.skip(apiTestFile.toPath(), "Test files never overwrite an existing file of the same name.");
} else {
File written = processTemplateToFile(operation, templateName, filename, generateApiTests, CodegenConstants.API_TESTS);
if (written != null) {
files.add(written);
if (config.isEnablePostProcessFile() && !dryRun) {
config.postProcessFile(written, "api-test");
}
}
} else if (dryRun) {
dryRunStatusMap.put(filename, new DryRunStatus(
apiTestFile.toPath(),
DryRunStatus.State.Skipped,
"Skipped by apiTests option supplied by user."
));
}
}
// to generate api documentation files
for (String templateName : config.apiDocTemplateFiles().keySet()) {
String filename = config.apiDocFilename(templateName, tag);
File apiDocFile = new File(filename);
if (generateApiDocumentation) {
if (!config.shouldOverwrite(filename) && apiDocFile.exists()) {
LOGGER.info("Skipped overwriting {}", filename);
if (dryRun) {
dryRunStatusMap.put(filename, new DryRunStatus(apiDocFile.toPath(), DryRunStatus.State.SkippedOverwrite));
}
continue;
File written = processTemplateToFile(operation, templateName, filename, generateApiDocumentation, CodegenConstants.API_DOCS);
if (written != null) {
files.add(written);
if (config.isEnablePostProcessFile() && !dryRun) {
config.postProcessFile(written, "api-doc");
}
File written = processTemplateToFile(operation, templateName, filename);
if (written != null) {
files.add(written);
if (config.isEnablePostProcessFile() && !dryRun) {
config.postProcessFile(written, "api-doc");
}
}
} else if (dryRun) {
dryRunStatusMap.put(filename, new DryRunStatus(
apiDocFile.toPath(),
DryRunStatus.State.Skipped,
"Skipped by apiDocs option supplied by user."
));
}
}
@ -752,84 +694,18 @@ public class DefaultGenerator extends AbstractGenerator implements Generator {
String outputFilename = new File(support.destinationFilename).isAbsolute() // split
? support.destinationFilename
: outputFolder + File.separator + support.destinationFilename.replace('/', File.separatorChar);
if (!config.shouldOverwrite(outputFilename)) {
LOGGER.info("Skipped overwriting {}", outputFilename);
if (dryRun) {
Path skippedSupportingFile = java.nio.file.Paths.get(outputFilename);
DryRunStatus status = new DryRunStatus(
skippedSupportingFile,
DryRunStatus.State.SkippedOverwrite
);
}
continue;
}
String templateFile;
if (support instanceof GlobalSupportingFile) {
templateFile = config.getCommonTemplateDir() + File.separator + support.templateFile;
} else {
templateFile = getFullTemplateFile(config, support.templateFile);
}
boolean shouldGenerate = true;
if (supportingFilesToGenerate != null && !supportingFilesToGenerate.isEmpty()) {
shouldGenerate = supportingFilesToGenerate.contains(support.destinationFilename);
}
if (!shouldGenerate) {
if (dryRun) {
Path skippedSupportingFile = java.nio.file.Paths.get(outputFilename);
DryRunStatus status = new DryRunStatus(
skippedSupportingFile,
DryRunStatus.State.Skipped,
"Skipped by supportingFiles option supplied by user."
);
dryRunStatusMap.put(outputFilename, status);
}
continue;
}
if (ignoreProcessor.allowsFile(new File(outputFilename))) {
// support.templateFile is the unmodified/original supporting file name (e.g. build.sh.mustache)
// templatingEngine.templateExists dispatches resolution to this, performing template-engine specific inspect of support file extensions.
if (templatingEngine.templateExists(this, support.templateFile)) {
String templateContent = templatingEngine.compileTemplate(this, bundle, support.templateFile);
writeToFile(outputFilename, templateContent);
File written = new File(outputFilename);
files.add(written);
if (config.isEnablePostProcessFile()) {
config.postProcessFile(written, "supporting-mustache");
}
} else {
if (Arrays.stream(templatingEngine.getFileExtensions()).anyMatch(templateFile::endsWith)) {
String templateContent = templatingEngine.compileTemplate(this, bundle, support.templateFile);
writeToFile(outputFilename, templateContent);
File written = new File(outputFilename);
files.add(written);
if (config.isEnablePostProcessFile()) {
config.postProcessFile(written, "supporting-mustache");
}
} else {
InputStream in = null;
try {
in = new FileInputStream(templateFile);
} catch (Exception e) {
// continue
}
if (in == null) {
in = this.getClass().getClassLoader().getResourceAsStream(getCPResourcePath(templateFile));
}
File outputFile = writeInputStreamToFile(outputFilename, in, templateFile);
files.add(outputFile);
if (config.isEnablePostProcessFile()) {
config.postProcessFile(outputFile, "supporting-common");
}
}
File written = processTemplateToFile(bundle, support.templateFile, outputFilename, shouldGenerate, CodegenConstants.SUPPORTING_FILES);
if (written != null) {
files.add(written);
if (config.isEnablePostProcessFile() && !dryRun) {
config.postProcessFile(written, "api-doc");
}
} else {
if (dryRun) {
dryRunStatusMap.put(outputFilename, new DryRunStatus(java.nio.file.Paths.get(outputFilename), DryRunStatus.State.Ignored));
}
LOGGER.info("Skipped generation of {} due to rule in .openapi-generator-ignore", outputFilename);
}
} catch (Exception e) {
throw new RuntimeException("Could not generate supporting file '" + support + "'", e);
@ -841,64 +717,27 @@ public class DefaultGenerator extends AbstractGenerator implements Generator {
final String openapiGeneratorIgnore = ".openapi-generator-ignore";
String ignoreFileNameTarget = config.outputFolder() + File.separator + openapiGeneratorIgnore;
File ignoreFile = new File(ignoreFileNameTarget);
if (generateMetadata && !ignoreFile.exists()) {
String ignoreFileNameSource = File.separator + config.getCommonTemplateDir() + File.separator + openapiGeneratorIgnore;
String ignoreFileContents = readResourceContents(ignoreFileNameSource);
try {
writeToFile(ignoreFileNameTarget, ignoreFileContents);
} catch (IOException e) {
throw new RuntimeException("Could not generate supporting file '" + openapiGeneratorIgnore + "'", e);
}
files.add(ignoreFile);
if (config.isEnablePostProcessFile() && !dryRun) {
config.postProcessFile(ignoreFile, "openapi-generator-ignore");
}
} else if (generateMetadata && dryRun && ignoreFile.exists()) {
dryRunStatusMap.put(ignoreFileNameTarget, new DryRunStatus(ignoreFile.toPath(), DryRunStatus.State.SkippedOverwrite));
} else if (!generateMetadata && dryRun) {
dryRunStatusMap.put(ignoreFileNameTarget, new DryRunStatus(
ignoreFile.toPath(),
DryRunStatus.State.Skipped,
"Skipped by generateMetadata option supplied by user"
));
}
String versionMetadata = config.outputFolder() + File.separator + METADATA_DIR + File.separator + "VERSION";
if (generateMetadata) {
File versionMetadataFile = new File(versionMetadata);
try {
writeToFile(versionMetadata, ImplementationVersion.read());
files.add(versionMetadataFile);
if (config.isEnablePostProcessFile() && !dryRun) {
config.postProcessFile(ignoreFile, "openapi-generator-version");
boolean shouldGenerate = !ignoreFile.exists();
if (shouldGenerate && supportingFilesToGenerate != null && !supportingFilesToGenerate.isEmpty()) {
shouldGenerate = supportingFilesToGenerate.contains(openapiGeneratorIgnore);
}
} catch (IOException e) {
throw new RuntimeException("Could not generate supporting file '" + versionMetadata + "'", e);
File written = processTemplateToFile(bundle, openapiGeneratorIgnore, ignoreFileNameTarget, shouldGenerate, CodegenConstants.SUPPORTING_FILES);
if (written != null) {
files.add(written);
if (config.isEnablePostProcessFile() && !dryRun) {
config.postProcessFile(written, "openapi-generator-ignore");
}
}
} catch (Exception e) {
throw new RuntimeException("Could not generate supporting file '" + ignoreFileNameTarget + "'", e);
}
} else if(!generateMetadata && dryRun) {
Path metadata = java.nio.file.Paths.get(versionMetadata);
DryRunStatus status = new DryRunStatus(metadata, DryRunStatus.State.Skipped, "Skipped by generateMetadata option supplied by user.");
dryRunStatusMap.put(versionMetadata, status);
} else {
this.templateProcessor.skip(ignoreFile.toPath(), "Skipped by generateMetadata option supplied by user.");
}
/*
* The following code adds default LICENSE (Apache-2.0) for all generators
* To use license other than Apache2.0, update the following file:
* modules/openapi-generator/src/main/resources/_common/LICENSE
*
final String apache2License = "LICENSE";
String licenseFileNameTarget = config.outputFolder() + File.separator + apache2License;
File licenseFile = new File(licenseFileNameTarget);
String licenseFileNameSource = File.separator + config.getCommonTemplateDir() + File.separator + apache2License;
String licenseFileContents = readResourceContents(licenseFileNameSource);
try {
writeToFile(licenseFileNameTarget, licenseFileContents);
} catch (IOException e) {
throw new RuntimeException("Could not generate LICENSE file '" + apache2License + "'", e);
}
files.add(licenseFile);
*/
generateVersionMetadata(files);
}
@SuppressWarnings("unchecked")
@ -1007,8 +846,7 @@ public class DefaultGenerator extends AbstractGenerator implements Generator {
configureGeneratorProperties();
configureOpenAPIInfo();
// If the template adapter is mustache, we'll set the config-modified Compiler.
configPostProcessMustacheCompiler();
config.processOpenAPI(openAPI);
List<File> files = new ArrayList<>();
// models
@ -1022,7 +860,6 @@ public class DefaultGenerator extends AbstractGenerator implements Generator {
// supporting files
Map<String, Object> bundle = buildSupportFileBundle(allOperations, allModels);
generateSupportingFiles(files, bundle);
config.processOpenAPI(openAPI);
if(dryRun) {
boolean verbose = Boolean.parseBoolean(GlobalSettings.getProperty("verbose"));
@ -1032,6 +869,8 @@ public class DefaultGenerator extends AbstractGenerator implements Generator {
sb.append("Dry Run Results:");
sb.append(System.lineSeparator()).append(System.lineSeparator());
Map<String, DryRunStatus> dryRunStatusMap = ((DryRunTemplateManager) this.templateProcessor).getDryRunStatusMap();
dryRunStatusMap.entrySet().stream().sorted(Map.Entry.comparingByKey()).forEach(entry -> {
DryRunStatus status = entry.getValue();
try {
@ -1060,36 +899,9 @@ public class DefaultGenerator extends AbstractGenerator implements Generator {
System.err.println(sb.toString());
} else {
if (generateMetadata) {
try {
StringBuilder sb = new StringBuilder();
File outDir = new File(this.config.getOutputDir());
List<File> filesToSort = new ArrayList<>();
// Avoid side-effecting sort in this path when generateMetadata=true
files.forEach(f -> {
// We have seen NPE on CI for getPath() returning null, so guard against this (to be fixed in 5.0 template management refactor)
//noinspection ConstantConditions
if (f != null && f.getPath() != null) {
filesToSort.add(f);
}
});
filesToSort.sort(PathFileComparator.PATH_COMPARATOR);
filesToSort.forEach(f -> {
String relativePath = outDir.toPath().relativize(f.toPath()).toString();
if (!relativePath.equals(METADATA_DIR + File.separator + "VERSION")) {
sb.append(relativePath).append(System.lineSeparator());
}
});
String targetFile = config.outputFolder() + File.separator + METADATA_DIR + File.separator + "FILES";
File filesFile = writeToFile(targetFile, sb.toString().getBytes(StandardCharsets.UTF_8));
files.add(filesFile);
} catch (Exception e) {
LOGGER.warn("Failed to write FILES metadata to track generated files.");
}
// This exists here rather than in the method which generates supporting files to avoid accidentally adding files after this metadata.
if (generateSupportingFiles) {
generateFilesMetadata(files);
}
}
@ -1099,37 +911,20 @@ public class DefaultGenerator extends AbstractGenerator implements Generator {
return files;
}
@Override
public String getFullTemplateContents(String templateName) {
return readTemplate(getFullTemplateFile(config, templateName));
}
/**
* Returns the path of a template, allowing access to the template where consuming literal contents aren't desirable or possible.
*
* @param name the template name (e.g. model.mustache)
* @return The {@link Path} to the template
*/
@Override
public Path getFullTemplatePath(String name) {
String fullPath = getFullTemplateFile(config, name);
return java.nio.file.Paths.get(fullPath);
}
protected File processTemplateToFile(Map<String, Object> templateData, String templateName, String outputFilename) throws IOException {
protected File processTemplateToFile(Map<String, Object> templateData, String templateName, String outputFilename, boolean shouldGenerate, String skippedByOption) throws IOException {
String adjustedOutputFilename = outputFilename.replaceAll("//", "/").replace('/', File.separatorChar);
File target = new File(adjustedOutputFilename);
if (ignoreProcessor.allowsFile(target)) {
String templateContent = templatingEngine.compileTemplate(this, templateData, templateName);
writeToFile(adjustedOutputFilename, templateContent);
return target;
} else if (this.dryRun) {
dryRunStatusMap.put(adjustedOutputFilename, new DryRunStatus(target.toPath(), DryRunStatus.State.Ignored));
return target;
if (shouldGenerate) {
return this.templateProcessor.write(templateData,templateName, target);
} else {
this.templateProcessor.skip(target.toPath(), String.format(Locale.ROOT, "Skipped by %s options supplied by user.", skippedByOption));
return null;
}
} else {
this.templateProcessor.ignore(target.toPath(), "Ignored by rule in ignore file.");
return null;
}
LOGGER.info("Skipped generation of {} due to rule in .openapi-generator-ignore", adjustedOutputFilename);
return null;
}
public Map<String, List<CodegenOperation>> processPaths(Paths paths) {
@ -1479,50 +1274,73 @@ public class DefaultGenerator extends AbstractGenerator implements Generator {
return result;
}
protected File writeInputStreamToFile(String filename, InputStream in, String templateFile) throws IOException {
if (in != null) {
byte[] bytes = IOUtils.toByteArray(in);
if (dryRun) {
Path path = java.nio.file.Paths.get(filename);
dryRunStatusMap.put(filename, new DryRunStatus(path));
return path.toFile();
/**
* Generates a file at .openapi-generator/VERSION to track the version of user's latest run.
*
* @param files The list tracking generated files
*/
private void generateVersionMetadata(List<File> files) {
String versionMetadata = config.outputFolder() + File.separator + METADATA_DIR + File.separator + "VERSION";
if (generateMetadata) {
File versionMetadataFile = new File(versionMetadata);
try {
File written = this.templateProcessor.writeToFile(versionMetadata, ImplementationVersion.read().getBytes(StandardCharsets.UTF_8));
if (written != null) {
files.add(versionMetadataFile);
if (config.isEnablePostProcessFile() && !dryRun) {
config.postProcessFile(written, "openapi-generator-version");
}
}
} catch (IOException e) {
throw new RuntimeException("Could not generate supporting file '" + versionMetadata + "'", e);
}
return writeToFile(filename, bytes);
} else {
LOGGER.error("can't open '{}' for input; cannot write '{}'", templateFile, filename);
if (dryRun) {
Path path = java.nio.file.Paths.get(filename);
dryRunStatusMap.put(filename, new DryRunStatus(path, DryRunStatus.State.Error));
}
return null;
Path metadata = java.nio.file.Paths.get(versionMetadata);
this.templateProcessor.skip(metadata, "Skipped by generateMetadata option supplied by user.");
}
}
/**
* Write bytes to a file
* Generates a file at .openapi-generator/FILES to track the files created by the user's latest run.
* This is ideal for CI and regeneration of code without stale/unused files from older generations.
*
* @param filename The name of file to write
* @param contents The contents bytes. Typically this is a UTF-8 formatted string.
* @return File representing the written file.
* @throws IOException If file cannot be written.
* @param files The list tracking generated files
*/
@Override
public File writeToFile(String filename, byte[] contents) throws IOException {
if (dryRun) {
Path path = java.nio.file.Paths.get(filename);
DryRunStatus status = new DryRunStatus(path);
if (getEnableMinimalUpdate()) {
status.setState(DryRunStatus.State.WriteIfNewer);
} else {
status.setState(DryRunStatus.State.Write);
}
private void generateFilesMetadata(List<File> files) {
if (generateMetadata) {
try {
StringBuilder sb = new StringBuilder();
File outDir = new File(this.config.getOutputDir());
dryRunStatusMap.put(filename, status);
return path.toFile();
} else {
return super.writeToFile(filename, contents);
List<File> filesToSort = new ArrayList<>();
// Avoid side-effecting sort in this path when generateMetadata=true
files.forEach(f -> {
// We have seen NPE on CI for getPath() returning null, so guard against this (to be fixed in 5.0 template management refactor)
//noinspection ConstantConditions
if (f != null && f.getPath() != null) {
filesToSort.add(f);
}
});
filesToSort.sort(PathFileComparator.PATH_COMPARATOR);
filesToSort.forEach(f -> {
String relativePath = outDir.toPath().relativize(f.toPath()).toString();
if (!relativePath.equals(METADATA_DIR + File.separator + "VERSION")) {
sb.append(relativePath).append(System.lineSeparator());
}
});
String targetFile = config.outputFolder() + File.separator + METADATA_DIR + File.separator + "FILES";
File filesFile = this.templateProcessor.writeToFile(targetFile, sb.toString().getBytes(StandardCharsets.UTF_8));
if (filesFile != null) {
files.add(filesFile);
}
} catch (Exception e) {
LOGGER.warn("Failed to write FILES metadata to track generated files.");
}
}
}
}

View File

@ -0,0 +1,107 @@
package org.openapitools.codegen;
import com.google.common.collect.ImmutableMap;
import org.openapitools.codegen.api.TemplateProcessor;
import org.openapitools.codegen.templating.TemplateManagerOptions;
import java.io.File;
import java.io.IOException;
import java.nio.file.Path;
import java.util.HashMap;
import java.util.Map;
/**
* Manages templates for a generator "dry run"
*/
public class DryRunTemplateManager implements TemplateProcessor {
private final TemplateManagerOptions options;
private final Map<String, DryRunStatus> dryRunStatusMap = new HashMap<>();
/**
* Constructs a new instance of {@link DryRunTemplateManager} for the provided options
*
* @param options Options pertaining to templates (reads and writes)
*/
public DryRunTemplateManager(TemplateManagerOptions options) {
this.options = options;
}
/**
* Gets the full status of this dry run.
*
* @return An immutable copy of the dry run status.
*/
public Map<String, DryRunStatus> getDryRunStatusMap() {
return ImmutableMap.copyOf(dryRunStatusMap);
}
/**
* Writes data to a compiled template
*
* @param data Input data
* @param template Input template location
* @param target The targeted file output location
* @return The actual file
*/
@Override
public File write(Map<String, Object> data, String template, File target) throws IOException {
if (this.options.isSkipOverwrite() && target.exists()) {
dryRunStatusMap.put(target.toString(),
new DryRunStatus(
target.toPath(),
DryRunStatus.State.SkippedOverwrite,
"File exists and skip overwrite option is enabled."
));
}
return target;
}
@Override
public File writeToFile(String filename, byte[] contents) throws IOException {
Path path = java.nio.file.Paths.get(filename);
DryRunStatus status = new DryRunStatus(path);
if (this.options.isMinimalUpdate()) {
status.setState(DryRunStatus.State.WriteIfNewer);
} else {
status.setState(DryRunStatus.State.Write);
}
dryRunStatusMap.put(filename, status);
return path.toFile();
}
@Override
public void ignore(Path path, String context) {
dryRunStatusMap.put(path.toString(),
new DryRunStatus(
path,
DryRunStatus.State.Ignored,
context
));
}
@Override
public void skip(Path path, String context) {
if (this.options.isSkipOverwrite() && path.toFile().exists()) {
dryRunStatusMap.put(path.toString(),
new DryRunStatus(
path,
DryRunStatus.State.SkippedOverwrite,
context
));
return;
}
dryRunStatusMap.put(path.toString(),
new DryRunStatus(
path,
DryRunStatus.State.Skipped,
context
));
}
@Override
public void error(Path path, String context) {
dryRunStatusMap.put(path.toString(), new DryRunStatus(path, DryRunStatus.State.Error));
}
}

View File

@ -1,29 +0,0 @@
/*
* Copyright 2018 OpenAPI-Generator Contributors (https://openapi-generator.tech)
* Copyright 2018 SmartBear Software
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.openapitools.codegen;
public class GlobalSupportingFile extends SupportingFile {
GlobalSupportingFile(String templateFile, String folder, String destinationFilename) {
super(templateFile, folder, destinationFilename);
}
GlobalSupportingFile(String templateFile, String destinationFilename) {
super(templateFile, destinationFilename);
}
}

View File

@ -0,0 +1,235 @@
package org.openapitools.codegen;
import org.apache.commons.lang3.StringUtils;
import org.openapitools.codegen.api.TemplatePathLocator;
import org.openapitools.codegen.api.TemplateProcessor;
import org.openapitools.codegen.api.TemplatingEngineAdapter;
import org.openapitools.codegen.api.TemplatingExecutor;
import org.openapitools.codegen.templating.TemplateManagerOptions;
import org.openapitools.codegen.templating.TemplateNotFoundException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.io.*;
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.nio.file.StandardCopyOption;
import java.util.Arrays;
import java.util.Map;
import java.util.Objects;
import java.util.Scanner;
import java.util.regex.Pattern;
/**
* Manages the lookup, compilation, and writing of template files
*/
public class TemplateManager implements TemplatingExecutor, TemplateProcessor {
private final TemplateManagerOptions options;
private final TemplatingEngineAdapter engineAdapter;
private final TemplatePathLocator[] templateLoaders;
private static final Logger LOGGER = LoggerFactory.getLogger(TemplateManager.class);
/**
* Constructs a new instance of a {@link TemplateManager}
*
* @param options The {@link TemplateManagerOptions} for reading and writing templates
* @param engineAdapter The adaptor to underlying templating engine
* @param templateLoaders Loaders which define where we look for templates
*/
public TemplateManager(
TemplateManagerOptions options,
TemplatingEngineAdapter engineAdapter,
TemplatePathLocator[] templateLoaders) {
this.options = options;
this.engineAdapter = engineAdapter;
this.templateLoaders = templateLoaders;
}
private String getFullTemplateFile(String name) {
String template = Arrays.stream(this.templateLoaders)
.map(i -> i.getFullTemplatePath(name))
.filter(Objects::nonNull)
.findFirst()
.orElse("");
if (StringUtils.isEmpty(template)) {
throw new TemplateNotFoundException(name);
}
return template;
}
/**
* returns the template content by name
*
* @param name the template name (e.g. model.mustache)
* @return the contents of that template
*/
@Override
public String getFullTemplateContents(String name) {
return readTemplate(getFullTemplateFile(name));
}
/**
* Returns the path of a template, allowing access to the template where consuming literal contents aren't desirable or possible.
*
* @param name the template name (e.g. model.mustache)
* @return The {@link Path} to the template
*/
@Override
public Path getFullTemplatePath(String name) {
return Paths.get(getFullTemplateFile(name));
}
/**
* Gets a normalized classpath resource location according to OS-specific file separator
*
* @param name The name of the resource file/directory to find
*
* @return A normalized string according to OS-specific file separator
*/
public static String getCPResourcePath(final String name) {
if (!"/".equals(File.separator)) {
return name.replaceAll(Pattern.quote(File.separator), "/");
}
return name;
}
/**
* Reads a template's contents from the specified location
*
* @param name The location of the template
* @return The raw template contents
*/
public String readTemplate(String name) {
try {
Reader reader = getTemplateReader(name);
if (reader == null) {
throw new RuntimeException("no file found");
}
Scanner s = new Scanner(reader).useDelimiter("\\A");
return s.hasNext() ? s.next() : "";
} catch (Exception e) {
LOGGER.error(e.getMessage());
}
throw new RuntimeException("can't load template " + name);
}
@SuppressWarnings("squid:S2095")
// ignored rule as used in the CLI and it's required to return a reader
public Reader getTemplateReader(String name) {
InputStream is = null;
try {
is = this.getClass().getClassLoader().getResourceAsStream(getCPResourcePath(name));
if (is == null) {
is = new FileInputStream(new File(name)); // May throw but never return a null value
}
return new InputStreamReader(is, StandardCharsets.UTF_8);
} catch (FileNotFoundException e) {
LOGGER.error(e.getMessage());
throw new RuntimeException("can't load template " + name);
}
}
/**
* Writes data to a compiled template
*
* @param data Input data
* @param template Input template location
* @param target The targeted file output location
*
* @return The actual file
*/
@Override
public File write(Map<String, Object> data, String template, File target) throws IOException {
String templateContent = this.engineAdapter.compileTemplate(this, data, template);
return writeToFile(target.getPath(), templateContent);
}
@Override
public void ignore(Path path, String context) {
LOGGER.info("Ignored {} ({})", path.toString(), context);
}
@Override
public void skip(Path path, String context) {
LOGGER.info("Skipped {} ({})", path.toString(), context);
}
/**
* Write String to a file, formatting as UTF-8
*
* @param filename The name of file to write
* @param contents The contents string.
* @return File representing the written file.
* @throws IOException If file cannot be written.
*/
public File writeToFile(String filename, String contents) throws IOException {
return writeToFile(filename, contents.getBytes(StandardCharsets.UTF_8));
}
/**
* Write bytes to a file
*
* @param filename The name of file to write
* @param contents The contents bytes. Typically, this is a UTF-8 formatted string.
* @return File representing the written file.
* @throws IOException If file cannot be written.
*/
public File writeToFile(String filename, byte[] contents) throws IOException {
// Use Paths.get here to normalize path (for Windows file separator, space escaping on Linux/Mac, etc)
File outputFile = Paths.get(filename).toFile();
if (this.options.isMinimalUpdate()) {
String tempFilename = filename + ".tmp";
File tempFile = null;
try {
tempFile = writeToFileRaw(tempFilename, contents);
if (!filesEqual(tempFile, outputFile)) {
LOGGER.info("writing file " + filename);
Files.move(tempFile.toPath(), outputFile.toPath(), StandardCopyOption.REPLACE_EXISTING);
tempFile = null;
} else {
LOGGER.info("skipping unchanged file " + filename);
}
} finally {
if (tempFile != null && tempFile.exists()) {
try {
tempFile.delete();
} catch (Exception ex) {
LOGGER.error("Error removing temporary file " + tempFile, ex);
}
}
}
} else {
LOGGER.info("writing file " + filename);
outputFile = writeToFileRaw(filename, contents);
}
return outputFile;
}
private File writeToFileRaw(String filename, byte[] contents) throws IOException {
// Use Paths.get here to normalize path (for Windows file separator, space escaping on Linux/Mac, etc)
File output = Paths.get(filename).toFile();
if (this.options.isSkipOverwrite() && output.exists()) {
LOGGER.info("skip overwrite of file " + filename);
return output;
}
if (output.getParent() != null && !new File(output.getParent()).exists()) {
File parent = Paths.get(output.getParent()).toFile();
parent.mkdirs();
}
Files.write(output.toPath(), contents);
return output;
}
private boolean filesEqual(File file1, File file2) throws IOException {
return file1.exists() && file2.exists() && Arrays.equals(Files.readAllBytes(file1.toPath()), Files.readAllBytes(file2.toPath()));
}
}

View File

@ -218,7 +218,7 @@ public abstract class AbstractPhpCodegen extends DefaultCodegen implements Codeg
// supportingFiles.add(new SupportingFile("LICENSE", "", "LICENSE"));
// all PHP codegens requires Composer, it means that we need to exclude from SVN at least vendor folder
supportingFiles.add(new SupportingFile(".gitignore", "", ".gitignore"));
supportingFiles.add(new SupportingFile("gitignore", "", ".gitignore"));
}
public String getPackageName() {

View File

@ -114,7 +114,7 @@ public class GraphQLNodeJSExpressServerCodegen extends AbstractGraphQLCodegen im
supportingFiles.add(new SupportingFile("schema.graphql.mustache", supportFolder, "schema.graphql"));
// General stuff
supportingFiles.add(new SupportingFile(".gitignore", supportFolder, ".gitignore"));
supportingFiles.add(new SupportingFile("gitignore", supportFolder, ".gitignore"));
supportingFiles.add(new SupportingFile("README.mustache", supportFolder, "README.md"));
supportingFiles.add(new SupportingFile("package.json.mustache", supportFolder, "package.json"));
supportingFiles.add(new SupportingFile("server.js", supportFolder, "server.js"));

View File

@ -125,7 +125,7 @@ public class PhpLaravelServerCodegen extends AbstractPhpCodegen {
supportingFiles.add(new SupportingFile(".env.example", outputFolder, ".env.example"));
supportingFiles.add(new SupportingFile("server.php", outputFolder, "server.php"));
supportingFiles.add(new SupportingFile("bootstrap/cache/.gitignore", outputFolder + File.separator + "bootstrap" + File.separator + "cache", ".gitignore"));
supportingFiles.add(new SupportingFile("bootstrap/cache/gitignore", outputFolder + File.separator + "bootstrap" + File.separator + "cache", ".gitignore"));
supportingFiles.add(new SupportingFile("bootstrap/app.php", outputFolder + File.separator + "bootstrap", "app.php"));
supportingFiles.add(new SupportingFile("bootstrap/testingAutoload.php", outputFolder + File.separator + "bootstrap", "testingAutoload.php"));
@ -169,7 +169,7 @@ public class PhpLaravelServerCodegen extends AbstractPhpCodegen {
supportingFiles.add(new SupportingFile("database/migrations/2014_10_12_000000_create_users_table.php", outputFolder + File.separator + "database" + File.separator + "migrations", "2014_10_12_000000_create_users_table.php"));
supportingFiles.add(new SupportingFile("database/migrations/2014_10_12_100000_create_password_resets_table.php", outputFolder + File.separator + "database" + File.separator + "migrations", "2014_10_12_100000_create_password_resets_table.php"));
supportingFiles.add(new SupportingFile("database/seeds/DatabaseSeeder.php", outputFolder + File.separator + "database" + File.separator + "seeds", "DatabaseSeeder.php"));
supportingFiles.add(new SupportingFile("database/.gitignore", outputFolder + File.separator + "database", ".gitignore"));
supportingFiles.add(new SupportingFile("database/gitignore", outputFolder + File.separator + "database", ".gitignore"));
// /config/
supportingFiles.add(new SupportingFile("config/app.php", outputFolder + File.separator + "config", "app.php"));
@ -199,14 +199,14 @@ public class PhpLaravelServerCodegen extends AbstractPhpCodegen {
supportingFiles.add(new SupportingFile("resources/views/welcome.blade.php", outputFolder + File.separator + "resources" + File.separator + "views", "welcome.blade.php"));
// /storage/
supportingFiles.add(new SupportingFile("storage/app/.gitignore", outputFolder + File.separator + "storage" + File.separator + "app", ".gitignore"));
supportingFiles.add(new SupportingFile("storage/app/public/.gitignore", outputFolder + File.separator + "storage" + File.separator + "app" + File.separator + "public", ".gitignore"));
supportingFiles.add(new SupportingFile("storage/framework/.gitignore", outputFolder + File.separator + "storage" + File.separator + "framework", ".gitignore"));
supportingFiles.add(new SupportingFile("storage/framework/cache/.gitignore", outputFolder + File.separator + "storage" + File.separator + "framework" + File.separator + "cache", ".gitignore"));
supportingFiles.add(new SupportingFile("storage/framework/sessions/.gitignore", outputFolder + File.separator + "storage" + File.separator + "framework" + File.separator + "sessions", ".gitignore"));
supportingFiles.add(new SupportingFile("storage/framework/testing/.gitignore", outputFolder + File.separator + "storage" + File.separator + "framework" + File.separator + "testing", ".gitignore"));
supportingFiles.add(new SupportingFile("storage/framework/views/.gitignore", outputFolder + File.separator + "storage" + File.separator + "framework" + File.separator + "views", ".gitignore"));
supportingFiles.add(new SupportingFile("storage/logs/.gitignore", outputFolder + File.separator + "storage" + File.separator + "logs", ".gitignore"));
supportingFiles.add(new SupportingFile("storage/app/gitignore", outputFolder + File.separator + "storage" + File.separator + "app", ".gitignore"));
supportingFiles.add(new SupportingFile("storage/app/public/gitignore", outputFolder + File.separator + "storage" + File.separator + "app" + File.separator + "public", ".gitignore"));
supportingFiles.add(new SupportingFile("storage/framework/gitignore", outputFolder + File.separator + "storage" + File.separator + "framework", ".gitignore"));
supportingFiles.add(new SupportingFile("storage/framework/cache/gitignore", outputFolder + File.separator + "storage" + File.separator + "framework" + File.separator + "cache", ".gitignore"));
supportingFiles.add(new SupportingFile("storage/framework/sessions/gitignore", outputFolder + File.separator + "storage" + File.separator + "framework" + File.separator + "sessions", ".gitignore"));
supportingFiles.add(new SupportingFile("storage/framework/testing/gitignore", outputFolder + File.separator + "storage" + File.separator + "framework" + File.separator + "testing", ".gitignore"));
supportingFiles.add(new SupportingFile("storage/framework/views/gitignore", outputFolder + File.separator + "storage" + File.separator + "framework" + File.separator + "views", ".gitignore"));
supportingFiles.add(new SupportingFile("storage/logs/gitignore", outputFolder + File.separator + "storage" + File.separator + "logs", ".gitignore"));
// /tests/
supportingFiles.add(new SupportingFile("tests/Feature/ExampleTest.php", outputFolder + File.separator + "tests" + File.separator + "Feature", "ExampleTest.php"));

View File

@ -133,7 +133,7 @@ public class PhpSilexServerCodegen extends DefaultCodegen implements CodegenConf
supportingFiles.add(new SupportingFile(".htaccess", "", ".htaccess"));
// remove this line when this class extends AbstractPhpCodegen
supportingFiles.add(new SupportingFile(".gitignore", "", ".gitignore"));
supportingFiles.add(new SupportingFile("gitignore", "", ".gitignore"));
}
@Override

View File

@ -0,0 +1,50 @@
package org.openapitools.codegen.templating;
import org.apache.commons.lang3.StringUtils;
import org.openapitools.codegen.TemplateManager;
import org.openapitools.codegen.api.TemplatePathLocator;
import java.io.File;
import java.net.URL;
/**
* Locates generator-agnostic templates from a common built-in location.
*/
public class CommonTemplateContentLocator implements TemplatePathLocator {
private String resourceLocation = "_common";
/**
* Constructs a new instance of {@link CommonTemplateContentLocator} defaulting to _common resource location.
*/
public CommonTemplateContentLocator() {
}
/**
* Constructs a new instance of {@link CommonTemplateContentLocator} for a targeted common location.
*
* @param resourceLocation A custom common file location.
*/
public CommonTemplateContentLocator(String resourceLocation) {
this.resourceLocation = resourceLocation;
}
/**
* Get the full path to a relative template file.
*
* @param relativeTemplateFile Template file
* @return String Full template file path
*/
@Override
public String getFullTemplatePath(String relativeTemplateFile) {
if (StringUtils.isNotEmpty(relativeTemplateFile)) {
String loc = this.resourceLocation + File.separator + relativeTemplateFile;
URL url = this.getClass().getClassLoader().getResource(TemplateManager.getCPResourcePath(loc));
if (url != null) {
return loc;
}
}
return null;
}
}

View File

@ -0,0 +1,91 @@
package org.openapitools.codegen.templating;
import org.apache.commons.lang3.StringUtils;
import org.openapitools.codegen.CodegenConfig;
import org.openapitools.codegen.TemplateManager;
import org.openapitools.codegen.api.TemplatePathLocator;
import java.io.File;
/**
* Locates templates according to {@link CodegenConfig} settings.
*/
public class GeneratorTemplateContentLocator implements TemplatePathLocator {
private final CodegenConfig codegenConfig;
/**
* Constructs a new instance of {@link GeneratorTemplateContentLocator} for the provided {@link CodegenConfig}
*
* @param codegenConfig A generator's configuration used for determining template file location.
*/
public GeneratorTemplateContentLocator(CodegenConfig codegenConfig) {
this.codegenConfig = codegenConfig;
}
private String buildLibraryFilePath(String dir, String library, String file) {
return dir + File.separator + "libraries" + File.separator + library + File.separator + file;
}
/**
* Determines whether an embedded file with the specified name exists.
*
* @param name The name of the file (i.e. relative to resource root)
*
* @return true if file is an embedded resource, false if it does not exist
*/
public boolean embeddedTemplateExists(String name) {
return this.getClass().getClassLoader().getResource(TemplateManager.getCPResourcePath(name)) != null;
}
/**
* Get the template file path with template dir prepended, and use the library template if exists.
*
* Precedence:
* 1) (template dir)/libraries/(library)
* 2) (template dir)
* 3) (embedded template dir)/libraries/(library)
* 4) (embedded template dir)
*
* Where "template dir" may be user defined and "embedded template dir" are the built-in templates for the given generator.
*
* @param relativeTemplateFile Template file
* @return String Full template file path
*/
@Override
public String getFullTemplatePath(String relativeTemplateFile) {
CodegenConfig config = this.codegenConfig;
//check the supplied template library folder for the file
final String library = config.getLibrary();
if (StringUtils.isNotEmpty(library)) {
//look for the file in the library subfolder of the supplied template
final String libTemplateFile = buildLibraryFilePath(config.templateDir(), library, relativeTemplateFile);
if (new File(libTemplateFile).exists() || this.getClass().getClassLoader().getResource(libTemplateFile) != null) {
return libTemplateFile;
}
}
//check the supplied template main folder for the file
final String template = config.templateDir() + File.separator + relativeTemplateFile;
if (new File(template).exists() || this.getClass().getClassLoader().getResource(template) != null) {
return template;
}
//try the embedded template library folder next
if (StringUtils.isNotEmpty(library)) {
final String embeddedLibTemplateFile = buildLibraryFilePath(config.embeddedTemplateDir(), library, relativeTemplateFile);
if (embeddedTemplateExists(embeddedLibTemplateFile)) {
// Fall back to the template file embedded/packaged in the JAR file library folder...
return embeddedLibTemplateFile;
}
}
// Fall back to the template file for generator root directory embedded/packaged in the JAR file...
String loc = config.embeddedTemplateDir() + File.separator + relativeTemplateFile;
if (embeddedTemplateExists(loc)) {
return loc;
}
return null;
}
}

View File

@ -30,7 +30,7 @@ import com.github.jknack.handlebars.io.StringTemplateSource;
import com.github.jknack.handlebars.io.TemplateLoader;
import com.github.jknack.handlebars.io.TemplateSource;
import org.openapitools.codegen.api.AbstractTemplatingEngineAdapter;
import org.openapitools.codegen.api.TemplatingGenerator;
import org.openapitools.codegen.api.TemplatingExecutor;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@ -38,7 +38,6 @@ import java.io.IOException;
import java.util.Locale;
import java.util.Map;
public class HandlebarsEngineAdapter extends AbstractTemplatingEngineAdapter {
static Logger LOGGER = LoggerFactory.getLogger(HandlebarsEngineAdapter.class);
private final String[] extensions = new String[]{"handlebars", "hbs"};
@ -53,12 +52,12 @@ public class HandlebarsEngineAdapter extends AbstractTemplatingEngineAdapter {
return "handlebars";
}
public String compileTemplate(TemplatingGenerator generator,
public String compileTemplate(TemplatingExecutor executor,
Map<String, Object> bundle, String templateFile) throws IOException {
TemplateLoader loader = new AbstractTemplateLoader() {
@Override
public TemplateSource sourceAt(String location) {
return findTemplate(generator, location);
return findTemplate(executor, location);
}
};
@ -83,14 +82,22 @@ public class HandlebarsEngineAdapter extends AbstractTemplatingEngineAdapter {
return tmpl.apply(context);
}
public TemplateSource findTemplate(TemplatingGenerator generator, String templateFile) {
for (String file : getModifiedFileLocation(templateFile)) {
public TemplateSource findTemplate(TemplatingExecutor generator, String templateFile) {
String[] possibilities = getModifiedFileLocation(templateFile);
for (String file : possibilities) {
try {
return new StringTemplateSource(file, generator.getFullTemplateContents(file));
} catch (Exception ignored) {
}
}
throw new TemplateNotFoundException(templateFile);
// allow lookup of files without extension modification (such as .openapi-generator-ignore, README.md, etc)
try {
return new StringTemplateSource(templateFile, generator.getFullTemplateContents(templateFile));
} catch (Exception ignored) {
}
throw new TemplateNotFoundException(String.join(", ", possibilities));
}
@Override

View File

@ -19,7 +19,7 @@ package org.openapitools.codegen.templating;
import com.samskivert.mustache.Mustache;
import com.samskivert.mustache.Template;
import org.openapitools.codegen.api.TemplatingEngineAdapter;
import org.openapitools.codegen.api.TemplatingGenerator;
import org.openapitools.codegen.api.TemplatingExecutor;
import java.io.IOException;
import java.io.Reader;
@ -42,24 +42,39 @@ public class MustacheEngineAdapter implements TemplatingEngineAdapter {
public String[] extensions = new String[]{"mustache"};
Mustache.Compiler compiler = Mustache.compiler();
/**
* Compiles a template into a string
*
* @param executor From where we can fetch the templates content (e.g. an instance of DefaultGenerator)
* @param bundle The map of values to pass to the template
* @param templateFile The name of the template (e.g. model.mustache )
* @return the processed template result
* @throws IOException an error ocurred in the template processing
*/
@Override
public String compileTemplate(TemplatingGenerator generator, Map<String, Object> bundle,
String templateFile) throws IOException {
public String compileTemplate(TemplatingExecutor executor, Map<String, Object> bundle, String templateFile) throws IOException {
Template tmpl = compiler
.withLoader(name -> findTemplate(generator, name))
.withLoader(name -> findTemplate(executor, name))
.defaultValue("")
.compile(generator.getFullTemplateContents(templateFile));
.compile(executor.getFullTemplateContents(templateFile));
return tmpl.execute(bundle);
}
public Reader findTemplate(TemplatingGenerator generator, String name) {
public Reader findTemplate(TemplatingExecutor generator, String name) {
for (String extension : extensions) {
try {
return new StringReader(generator.getFullTemplateContents(name + "." + extension));
} catch (Exception ignored) {
}
}
// support files without targeted extension (e.g. .gitignore, README.md), etc.
try {
return new StringReader(generator.getFullTemplateContents(name));
} catch (Exception ignored) {
}
throw new TemplateNotFoundException(name);
}

View File

@ -0,0 +1,45 @@
package org.openapitools.codegen.templating;
/**
* Holds the options relevant to template management and execution.
*/
public class TemplateManagerOptions {
private final boolean minimalUpdate;
private final boolean skipOverwrite;
/**
* Constructs a new instance of {@link TemplateManagerOptions}
*
* @param minimalUpdate See {@link #isMinimalUpdate()}
* @param skipOverwrite See {@link #isSkipOverwrite()}
*/
public TemplateManagerOptions(boolean minimalUpdate, boolean skipOverwrite) {
this.minimalUpdate = minimalUpdate;
this.skipOverwrite = skipOverwrite;
}
/**
* Determines whether the template should minimally update a target file.
*
* A minimal update means the template manager is requested to update a file only if it is newer.
*
* This option avoids "touching" a file and causing the last modification time (mtime) to change.
*
* @return true to prefer updating only changed files, false to disable that suggestion
*/
public boolean isMinimalUpdate() {
return minimalUpdate;
}
/**
* Determines whether the template manager should avoid overwriting an existing file.
*
* This differs from requesting {@link #isMinimalUpdate()} which evaluates contents, while this option only
* evaluates whether the file exists.
*
* @return true to avoid overwriting existing files (where supported), false to disable that suggestion.
*/
public boolean isSkipOverwrite() {
return skipOverwrite;
}
}

View File

@ -0,0 +1,74 @@
# Created by https://www.gitignore.io/api/osx,linux,windows
# Edit at https://www.gitignore.io/?templates=osx,linux,windows
### Linux ###
*~
# temporary files which can be created if a process still has a handle open of a deleted file
.fuse_hidden*
# KDE directory preferences
.directory
# Linux trash folder which might appear on any partition or disk
.Trash-*
# .nfs files are created when an open file is removed but is still being accessed
.nfs*
### OSX ###
# General
.DS_Store
.AppleDouble
.LSOverride
# Icon must end with two \r
Icon
# Thumbnails
._*
# Files that might appear in the root of a volume
.DocumentRevisions-V100
.fseventsd
.Spotlight-V100
.TemporaryItems
.Trashes
.VolumeIcon.icns
.com.apple.timemachine.donotpresent
# Directories potentially created on remote AFP share
.AppleDB
.AppleDesktop
Network Trash Folder
Temporary Items
.apdisk
### Windows ###
# Windows thumbnail cache files
Thumbs.db
Thumbs.db:encryptable
ehthumbs.db
ehthumbs_vista.db
# Dump file
*.stackdump
# Folder config file
[Dd]esktop.ini
# Recycle Bin used on file shares
$RECYCLE.BIN/
# Windows Installer files
*.cab
*.msi
*.msix
*.msm
*.msp
# Windows shortcuts
*.lnk
# End of https://www.gitignore.io/api/osx,linux,windows

View File

@ -1,201 +0,0 @@
Apache License
Version 2.0, January 2004
http://www.apache.org/licenses/
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
1. Definitions.
"License" shall mean the terms and conditions for use, reproduction,
and distribution as defined by Sections 1 through 9 of this document.
"Licensor" shall mean the copyright owner or entity authorized by
the copyright owner that is granting the License.
"Legal Entity" shall mean the union of the acting entity and all
other entities that control, are controlled by, or are under common
control with that entity. For the purposes of this definition,
"control" means (i) the power, direct or indirect, to cause the
direction or management of such entity, whether by contract or
otherwise, or (ii) ownership of fifty percent (50%) or more of the
outstanding shares, or (iii) beneficial ownership of such entity.
"You" (or "Your") shall mean an individual or Legal Entity
exercising permissions granted by this License.
"Source" form shall mean the preferred form for making modifications,
including but not limited to software source code, documentation
source, and configuration files.
"Object" form shall mean any form resulting from mechanical
transformation or translation of a Source form, including but
not limited to compiled object code, generated documentation,
and conversions to other media types.
"Work" shall mean the work of authorship, whether in Source or
Object form, made available under the License, as indicated by a
copyright notice that is included in or attached to the work
(an example is provided in the Appendix below).
"Derivative Works" shall mean any work, whether in Source or Object
form, that is based on (or derived from) the Work and for which the
editorial revisions, annotations, elaborations, or other modifications
represent, as a whole, an original work of authorship. For the purposes
of this License, Derivative Works shall not include works that remain
separable from, or merely link (or bind by name) to the interfaces of,
the Work and Derivative Works thereof.
"Contribution" shall mean any work of authorship, including
the original version of the Work and any modifications or additions
to that Work or Derivative Works thereof, that is intentionally
submitted to Licensor for inclusion in the Work by the copyright owner
or by an individual or Legal Entity authorized to submit on behalf of
the copyright owner. For the purposes of this definition, "submitted"
means any form of electronic, verbal, or written communication sent
to the Licensor or its representatives, including but not limited to
communication on electronic mailing lists, source code control systems,
and issue tracking systems that are managed by, or on behalf of, the
Licensor for the purpose of discussing and improving the Work, but
excluding communication that is conspicuously marked or otherwise
designated in writing by the copyright owner as "Not a Contribution."
"Contributor" shall mean Licensor and any individual or Legal Entity
on behalf of whom a Contribution has been received by Licensor and
subsequently incorporated within the Work.
2. Grant of Copyright License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
copyright license to reproduce, prepare Derivative Works of,
publicly display, publicly perform, sublicense, and distribute the
Work and such Derivative Works in Source or Object form.
3. Grant of Patent License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
(except as stated in this section) patent license to make, have made,
use, offer to sell, sell, import, and otherwise transfer the Work,
where such license applies only to those patent claims licensable
by such Contributor that are necessarily infringed by their
Contribution(s) alone or by combination of their Contribution(s)
with the Work to which such Contribution(s) was submitted. If You
institute patent litigation against any entity (including a
cross-claim or counterclaim in a lawsuit) alleging that the Work
or a Contribution incorporated within the Work constitutes direct
or contributory patent infringement, then any patent licenses
granted to You under this License for that Work shall terminate
as of the date such litigation is filed.
4. Redistribution. You may reproduce and distribute copies of the
Work or Derivative Works thereof in any medium, with or without
modifications, and in Source or Object form, provided that You
meet the following conditions:
(a) You must give any other recipients of the Work or
Derivative Works a copy of this License; and
(b) You must cause any modified files to carry prominent notices
stating that You changed the files; and
(c) You must retain, in the Source form of any Derivative Works
that You distribute, all copyright, patent, trademark, and
attribution notices from the Source form of the Work,
excluding those notices that do not pertain to any part of
the Derivative Works; and
(d) If the Work includes a "NOTICE" text file as part of its
distribution, then any Derivative Works that You distribute must
include a readable copy of the attribution notices contained
within such NOTICE file, excluding those notices that do not
pertain to any part of the Derivative Works, in at least one
of the following places: within a NOTICE text file distributed
as part of the Derivative Works; within the Source form or
documentation, if provided along with the Derivative Works; or,
within a display generated by the Derivative Works, if and
wherever such third-party notices normally appear. The contents
of the NOTICE file are for informational purposes only and
do not modify the License. You may add Your own attribution
notices within Derivative Works that You distribute, alongside
or as an addendum to the NOTICE text from the Work, provided
that such additional attribution notices cannot be construed
as modifying the License.
You may add Your own copyright statement to Your modifications and
may provide additional or different license terms and conditions
for use, reproduction, or distribution of Your modifications, or
for any such Derivative Works as a whole, provided Your use,
reproduction, and distribution of the Work otherwise complies with
the conditions stated in this License.
5. Submission of Contributions. Unless You explicitly state otherwise,
any Contribution intentionally submitted for inclusion in the Work
by You to the Licensor shall be under the terms and conditions of
this License, without any additional terms or conditions.
Notwithstanding the above, nothing herein shall supersede or modify
the terms of any separate license agreement you may have executed
with Licensor regarding such Contributions.
6. Trademarks. This License does not grant permission to use the trade
names, trademarks, service marks, or product names of the Licensor,
except as required for reasonable and customary use in describing the
origin of the Work and reproducing the content of the NOTICE file.
7. Disclaimer of Warranty. Unless required by applicable law or
agreed to in writing, Licensor provides the Work (and each
Contributor provides its Contributions) on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
implied, including, without limitation, any warranties or conditions
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
PARTICULAR PURPOSE. You are solely responsible for determining the
appropriateness of using or redistributing the Work and assume any
risks associated with Your exercise of permissions under this License.
8. Limitation of Liability. In no event and under no legal theory,
whether in tort (including negligence), contract, or otherwise,
unless required by applicable law (such as deliberate and grossly
negligent acts) or agreed to in writing, shall any Contributor be
liable to You for damages, including any direct, indirect, special,
incidental, or consequential damages of any character arising as a
result of this License or out of the use or inability to use the
Work (including but not limited to damages for loss of goodwill,
work stoppage, computer failure or malfunction, or any and all
other commercial damages or losses), even if such Contributor
has been advised of the possibility of such damages.
9. Accepting Warranty or Additional Liability. While redistributing
the Work or Derivative Works thereof, You may choose to offer,
and charge a fee for, acceptance of support, warranty, indemnity,
or other liability obligations and/or rights consistent with this
License. However, in accepting such obligations, You may act only
on Your own behalf and on Your sole responsibility, not on behalf
of any other Contributor, and only if You agree to indemnify,
defend, and hold each Contributor harmless for any liability
incurred by, or claims asserted against, such Contributor by reason
of your accepting any such warranty or additional liability.
END OF TERMS AND CONDITIONS
APPENDIX: How to apply the Apache License to your work.
To apply the Apache License to your work, attach the following
boilerplate notice, with the fields enclosed by brackets "{}"
replaced with your own identifying information. (Don't include
the brackets!) The text should be enclosed in the appropriate
comment syntax for the file format. We also recommend that a
file or class name and description of purpose be included on the
same "printed page" as the copyright notice for easier
identification within third-party archives.
Copyright {yyyy} {name of copyright owner}
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
https://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.

View File

@ -113,7 +113,7 @@ impl Request {
let mut path = self.path;
for (k, v) in self.path_params {
// replace {id} with the value of the id path param
path = path.replace(&format!("{{{}}}", k), &v);
{{=<% %>=}}path = path.replace(&format!("{{{}}}", k), &v);<%={{ }}=%>
}
for (k, v) in self.header_params {

View File

@ -1,6 +1,5 @@
package org.openapitools.codegen;
import io.swagger.models.Response;
import io.swagger.v3.oas.models.OpenAPI;
import io.swagger.v3.oas.models.Operation;
import io.swagger.v3.oas.models.PathItem;
@ -8,23 +7,361 @@ import io.swagger.v3.oas.models.Paths;
import io.swagger.v3.oas.models.media.IntegerSchema;
import io.swagger.v3.oas.models.media.Schema;
import io.swagger.v3.oas.models.media.StringSchema;
import io.swagger.v3.oas.models.parameters.Parameter;
import io.swagger.v3.oas.models.parameters.QueryParameter;
import io.swagger.v3.oas.models.parameters.RequestBody;
import io.swagger.v3.oas.models.responses.ApiResponse;
import io.swagger.v3.oas.models.responses.ApiResponses;
import org.openapitools.codegen.config.CodegenConfigurator;
import org.openapitools.codegen.config.GlobalSettings;
import org.openapitools.codegen.utils.ModelUtils;
import org.testng.Assert;
import org.testng.annotations.Test;
import java.io.File;
import java.io.IOException;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.StandardOpenOption;
import java.util.*;
public class DefaultGeneratorTest {
@Test
public void testIgnoreFileProcessing() throws IOException {
Path target = Files.createTempDirectory("test");
File output = target.toFile();
try {
List<String> ignoreFile = Arrays.asList(
".travis.yml",
"build.sbt",
"src/main/AndroidManifest.xml",
"pom.xml",
"src/test/**",
"src/main/java/org/openapitools/client/api/UserApi.java"
);
File ignorePath = new File(output, ".openapi-generator-ignore");
Files.write(ignorePath.toPath(),
String.join(System.lineSeparator(), ignoreFile).getBytes(StandardCharsets.UTF_8),
StandardOpenOption.CREATE);
final CodegenConfigurator configurator = new CodegenConfigurator()
.setGeneratorName("java")
.setInputSpec("src/test/resources/3_0/petstore.yaml")
.setOutputDir(target.toAbsolutePath().toString());
final ClientOptInput clientOptInput = configurator.toClientOptInput();
DefaultGenerator generator = new DefaultGenerator(false);
generator.setGeneratorPropertyDefault(CodegenConstants.MODELS, "true");
generator.setGeneratorPropertyDefault(CodegenConstants.MODEL_TESTS, "true");
generator.setGeneratorPropertyDefault(CodegenConstants.MODEL_DOCS, "false");
generator.setGeneratorPropertyDefault(CodegenConstants.APIS, "true");
generator.setGeneratorPropertyDefault(CodegenConstants.SUPPORTING_FILES, "true");
generator.setGeneratorPropertyDefault(CodegenConstants.API_DOCS, "false");
generator.setGeneratorPropertyDefault(CodegenConstants.MODEL_TESTS, "true");
generator.setGeneratorPropertyDefault(CodegenConstants.API_TESTS, "false");
List<File> files = generator.opts(clientOptInput).generate();
Assert.assertEquals(files.size(), 44);
// Check expected generated files
// api sanity check
TestUtils.ensureContainsFile(files, output, "src/main/java/org/openapitools/client/api/PetApi.java");
Assert.assertTrue(new File(output, "src/main/java/org/openapitools/client/api/PetApi.java").exists());
// model sanity check
TestUtils.ensureContainsFile(files, output, "src/main/java/org/openapitools/client/model/Category.java");
Assert.assertTrue(new File(output, "src/main/java/org/openapitools/client/model/Category.java").exists());
TestUtils.ensureContainsFile(files, output, "src/main/java/org/openapitools/client/model/ModelApiResponse.java");
Assert.assertTrue(new File(output, "src/main/java/org/openapitools/client/model/ModelApiResponse.java").exists());
// supporting files sanity check
TestUtils.ensureContainsFile(files, output, "build.gradle");
Assert.assertTrue(new File(output, "build.gradle").exists());
TestUtils.ensureContainsFile(files, output, "api/openapi.yaml");
Assert.assertTrue(new File(output, "build.gradle").exists());
// Check excluded files
TestUtils.ensureDoesNotContainsFile(files, output, ".travis.yml");
Assert.assertFalse(new File(output, ".travis.yml").exists());
TestUtils.ensureDoesNotContainsFile(files, output, "build.sbt");
Assert.assertFalse(new File(output, "build.sbt").exists());
TestUtils.ensureDoesNotContainsFile(files, output, "src/main/AndroidManifest.xml");
Assert.assertFalse(new File(output, "src/main/AndroidManifest.xml").exists());
TestUtils.ensureDoesNotContainsFile(files, output, "pom.xml");
Assert.assertFalse(new File(output, "pom.xml").exists());
TestUtils.ensureDoesNotContainsFile(files, output, "src/test/java/org/openapitools/client/model/CategoryTest.java");
Assert.assertFalse(new File(output, "src/test/java/org/openapitools/client/model/CategoryTest.java").exists());
TestUtils.ensureDoesNotContainsFile(files, output, "src/main/java/org/openapitools/client/api/UserApi.java");
Assert.assertFalse(new File(output, "src/main/java/org/openapitools/client/api/UserApi.java").exists());
} finally {
output.delete();
}
}
@SuppressWarnings("ResultOfMethodCallIgnored")
@Test
public void testFilesAreNeverOverwritten() throws IOException {
Path target = Files.createTempDirectory("test");
File output = target.toFile();
try {
final CodegenConfigurator configurator = new CodegenConfigurator()
.setGeneratorName("java")
.setInputSpec("src/test/resources/3_0/petstore.yaml")
.setSkipOverwrite(false)
.setOutputDir(target.toAbsolutePath().toString());
// Create "existing" files
String apiTestRelativePath = "src/test/java/org/openapitools/client/api/PetApiTest.java";
String modelTestRelativePath = "src/test/java/org/openapitools/client/model/CategoryTest.java";
File apiTestFile = new File(output, apiTestRelativePath);
new File(apiTestFile.getParent()).mkdirs();
Files.write(apiTestFile.toPath(),
"empty".getBytes(StandardCharsets.UTF_8),
StandardOpenOption.CREATE);
File modelTestFile = new File(output, modelTestRelativePath);
new File(modelTestFile.getParent()).mkdirs();
Files.write(modelTestFile.toPath(),
"empty".getBytes(StandardCharsets.UTF_8),
StandardOpenOption.CREATE);
final ClientOptInput clientOptInput = configurator.toClientOptInput();
DefaultGenerator generator = new DefaultGenerator(false);
generator.setGeneratorPropertyDefault(CodegenConstants.MODELS, "true");
generator.setGeneratorPropertyDefault(CodegenConstants.MODEL_DOCS, "false");
generator.setGeneratorPropertyDefault(CodegenConstants.APIS, "true");
generator.setGeneratorPropertyDefault(CodegenConstants.SUPPORTING_FILES, "false");
generator.setGeneratorPropertyDefault(CodegenConstants.API_DOCS, "false");
generator.setGeneratorPropertyDefault(CodegenConstants.MODEL_TESTS, "true");
generator.setGeneratorPropertyDefault(CodegenConstants.API_TESTS, "true");
List<File> files = generator.opts(clientOptInput).generate();
Assert.assertEquals(files.size(), 20);
// Check API is written and Test is not
TestUtils.ensureContainsFile(files, output, "src/main/java/org/openapitools/client/api/PetApi.java");
Assert.assertTrue(new File(output, "src/main/java/org/openapitools/client/api/PetApi.java").exists());
TestUtils.ensureDoesNotContainsFile(files, output, apiTestRelativePath);
Assert.assertTrue(apiTestFile.exists());
String apiTestContents = Files.readAllLines(apiTestFile.toPath()).get(0);
Assert.assertEquals(apiTestContents, "empty", "Expected test file to retain original contents.");
// Check Model is written and Test is not
TestUtils.ensureContainsFile(files, output, "src/main/java/org/openapitools/client/model/Category.java");
Assert.assertTrue(new File(output, "src/test/java/org/openapitools/client/model/CategoryTest.java").exists());
TestUtils.ensureDoesNotContainsFile(files, output, modelTestRelativePath);
Assert.assertTrue(modelTestFile.exists());
String modelTestContents = Files.readAllLines(modelTestFile.toPath()).get(0);
Assert.assertEquals(modelTestContents, "empty", "Expected test file to retain original contents.");
} finally {
output.delete();
}
}
@Test
public void dryRunWithApisOnly() throws IOException {
Path target = Files.createTempDirectory("test");
File output = target.toFile();
try {
final CodegenConfigurator configurator = new CodegenConfigurator()
.setGeneratorName("java")
.setInputSpec("src/test/resources/3_0/pingSomeObj.yaml")
.setOutputDir(target.toAbsolutePath().toString());
final ClientOptInput clientOptInput = configurator.toClientOptInput();
DefaultGenerator generator = new DefaultGenerator(true);
generator.setGeneratorPropertyDefault(CodegenConstants.MODELS, "false");
generator.setGeneratorPropertyDefault(CodegenConstants.MODEL_TESTS, "false");
generator.setGeneratorPropertyDefault(CodegenConstants.MODEL_DOCS, "false");
generator.setGeneratorPropertyDefault(CodegenConstants.APIS, "true");
generator.setGeneratorPropertyDefault(CodegenConstants.SUPPORTING_FILES, "false");
generator.setGeneratorPropertyDefault(CodegenConstants.API_DOCS, "false");
generator.setGeneratorPropertyDefault(CodegenConstants.MODEL_TESTS, "false");
generator.setGeneratorPropertyDefault(CodegenConstants.API_TESTS, "false");
List<File> files = generator.opts(clientOptInput).generate();
Assert.assertEquals(files.size(), 1);
TestUtils.ensureContainsFile(files, output, "src/main/java/org/openapitools/client/api/PingApi.java");
} finally {
output.delete();
}
}
@Test
public void dryRunWithModelsOnly() throws IOException {
Path target = Files.createTempDirectory("test");
File output = target.toFile();
try {
final CodegenConfigurator configurator = new CodegenConfigurator()
.setGeneratorName("java")
.setInputSpec("src/test/resources/3_0/pingSomeObj.yaml")
.setOutputDir(target.toAbsolutePath().toString());
final ClientOptInput clientOptInput = configurator.toClientOptInput();
DefaultGenerator generator = new DefaultGenerator(true);
generator.setGeneratorPropertyDefault(CodegenConstants.MODELS, "true");
generator.setGeneratorPropertyDefault(CodegenConstants.MODEL_TESTS, "false");
generator.setGeneratorPropertyDefault(CodegenConstants.MODEL_DOCS, "false");
generator.setGeneratorPropertyDefault(CodegenConstants.APIS, "false");
generator.setGeneratorPropertyDefault(CodegenConstants.SUPPORTING_FILES, "false");
generator.setGeneratorPropertyDefault(CodegenConstants.API_DOCS, "false");
generator.setGeneratorPropertyDefault(CodegenConstants.MODEL_TESTS, "false");
generator.setGeneratorPropertyDefault(CodegenConstants.API_TESTS, "false");
List<File> files = generator.opts(clientOptInput).generate();
Assert.assertEquals(files.size(), 1);
TestUtils.ensureContainsFile(files, output, "src/main/java/org/openapitools/client/model/SomeObj.java");
} finally {
output.delete();
}
}
@Test
public void dryRunWithSupportFilesSelections() throws IOException {
Path target = Files.createTempDirectory("test");
File output = target.toFile();
try {
final CodegenConfigurator configurator = new CodegenConfigurator()
.setGeneratorName("java")
.setInputSpec("src/test/resources/3_0/pingSomeObj.yaml")
.setOutputDir(target.toAbsolutePath().toString());
final ClientOptInput clientOptInput = configurator.toClientOptInput();
DefaultGenerator generator = new DefaultGenerator(true);
generator.setGeneratorPropertyDefault(CodegenConstants.MODELS, "false");
generator.setGeneratorPropertyDefault(CodegenConstants.MODEL_TESTS, "false");
generator.setGeneratorPropertyDefault(CodegenConstants.MODEL_DOCS, "false");
generator.setGeneratorPropertyDefault(CodegenConstants.APIS, "false");
generator.setGeneratorPropertyDefault(CodegenConstants.SUPPORTING_FILES, "true");
generator.setGeneratorPropertyDefault(CodegenConstants.API_DOCS, "false");
generator.setGeneratorPropertyDefault(CodegenConstants.MODEL_TESTS, "false");
generator.setGeneratorPropertyDefault(CodegenConstants.API_TESTS, "false");
List<String> filesToGenerate = Arrays.asList(
"pom.xml",
".travis.yml",
".gitignore",
"git_push.sh"
);
GlobalSettings.setProperty(CodegenConstants.SUPPORTING_FILES, String.join(",", filesToGenerate));
List<File> files = generator.opts(clientOptInput).generate();
Assert.assertEquals(files.size(), 5);
TestUtils.ensureContainsFile(files, output, "pom.xml");
TestUtils.ensureContainsFile(files, output, ".travis.yml");
TestUtils.ensureContainsFile(files, output, ".gitignore");
TestUtils.ensureContainsFile(files, output, "git_push.sh");
TestUtils.ensureContainsFile(files, output, ".openapi-generator/VERSION");
} finally {
GlobalSettings.reset();
output.delete();
}
}
@Test
public void supportCustomTemplateEngine() throws IOException {
Path target = Files.createTempDirectory("test");
File templateDir = new File(target.toFile(), "template");
Files.createDirectory(templateDir.toPath());
File output = new File(target.toFile(), "out");
Files.createDirectory(output.toPath());
try {
final CodegenConfigurator configurator = new CodegenConfigurator()
.setGeneratorName("jmeter")
.setInputSpec("src/test/resources/3_0/pingSomeObj.yaml")
.setSkipOverwrite(false)
.setTemplateDir(templateDir.toPath().toAbsolutePath().toString())
.setTemplatingEngineName("handlebars")
.setOutputDir(output.toPath().toAbsolutePath().toString());
// Create custom template directory
Files.copy(
Objects.requireNonNull(this.getClass().getClassLoader().getResourceAsStream("templating/templates/jmeter/api.hbs")),
new File(templateDir, "api.hbs").toPath());
Files.copy(
Objects.requireNonNull(this.getClass().getClassLoader().getResourceAsStream("templating/templates/jmeter/testdata-localhost.hbs")),
new File(templateDir, "testdata-localhost.hbs").toPath());
final ClientOptInput clientOptInput = configurator.toClientOptInput();
DefaultGenerator generator = new DefaultGenerator(false);
List<File> files = generator.opts(clientOptInput).generate();
Assert.assertEquals(files.size(), 5);
// Check API is written and Test is not
TestUtils.ensureContainsFile(files, output, "PingApi.jmx");
Assert.assertTrue(new File(output, "PingApi.jmx").exists());
TestUtils.ensureContainsFile(files, output, "PingApi.csv");
Assert.assertTrue(new File(output, "PingApi.csv").exists());
TestUtils.ensureContainsFile(files, output, ".openapi-generator-ignore");
Assert.assertTrue(new File(output, ".openapi-generator-ignore").exists());
TestUtils.ensureContainsFile(files, output, ".openapi-generator/VERSION");
Assert.assertTrue(new File(output, ".openapi-generator/VERSION").exists());
TestUtils.ensureContainsFile(files, output, ".openapi-generator/FILES");
Assert.assertTrue(new File(output, ".openapi-generator/FILES").exists());
TestUtils.assertFileContains(java.nio.file.Paths.get(output + "/PingApi.jmx"), "PingApi Test Plan via Handlebars");
TestUtils.assertFileContains(java.nio.file.Paths.get(output + "/PingApi.csv"),
"testCase,httpStatusCode,someObj",
"Success,200,0");
} finally {
output.delete();
}
}
@Test
public void testNonStrictProcessPaths() throws Exception {
OpenAPI openAPI = TestUtils.createOpenAPI();
openAPI.setPaths(new Paths());
openAPI.getPaths().addPathItem("path1/", new PathItem().get(new Operation().operationId("op1").responses(new ApiResponses().addApiResponse("201", new ApiResponse().description("OK")))));
openAPI.getPaths().addPathItem("path2/", new PathItem().get(new Operation().operationId("op2").addParametersItem(new QueryParameter().name("p1").schema(new StringSchema())).responses(new ApiResponses().addApiResponse("201", new ApiResponse().description("OK")))));
ClientOptInput opts = new ClientOptInput();
opts.setOpenAPI(openAPI);
CodegenConfig config = new DefaultCodegen();
config.setStrictSpecBehavior(false);
opts.setConfig(config);
DefaultGenerator generator = new DefaultGenerator();
generator.opts(opts);
Map<String, List<CodegenOperation>> result = generator.processPaths(openAPI.getPaths());
Assert.assertEquals(result.size(), 1);
List<CodegenOperation> defaultList = result.get("Default");
Assert.assertEquals(defaultList.size(), 2);
Assert.assertEquals(defaultList.get(0).path, "path1/");
Assert.assertEquals(defaultList.get(0).allParams.size(), 0);
Assert.assertEquals(defaultList.get(1).path, "path2/");
Assert.assertEquals(defaultList.get(1).allParams.size(), 1);
}
@Test
public void testProcessPaths() throws Exception {
OpenAPI openAPI = TestUtils.createOpenAPI();
@ -54,34 +391,8 @@ public class DefaultGeneratorTest {
Assert.assertEquals(defaultList.get(3).allParams.size(), 1);
}
@Test
public void testNonStrictProcessPaths() throws Exception {
OpenAPI openAPI = TestUtils.createOpenAPI();
openAPI.setPaths(new Paths());
openAPI.getPaths().addPathItem("path1/", new PathItem().get(new Operation().operationId("op1").responses(new ApiResponses().addApiResponse("201", new ApiResponse().description("OK")))));
openAPI.getPaths().addPathItem("path2/", new PathItem().get(new Operation().operationId("op2").addParametersItem(new QueryParameter().name("p1").schema(new StringSchema())).responses(new ApiResponses().addApiResponse("201", new ApiResponse().description("OK")))));
ClientOptInput opts = new ClientOptInput();
opts.setOpenAPI(openAPI);
CodegenConfig config = new DefaultCodegen();
config.setStrictSpecBehavior(false);
opts.setConfig(config);
DefaultGenerator generator = new DefaultGenerator();
generator.opts(opts);
Map<String, List<CodegenOperation>> result = generator.processPaths(openAPI.getPaths());
Assert.assertEquals(result.size(), 1);
List<CodegenOperation> defaultList = result.get("Default");
Assert.assertEquals(defaultList.size(), 2);
Assert.assertEquals(defaultList.get(0).path, "path1/");
Assert.assertEquals(defaultList.get(0).allParams.size(), 0);
Assert.assertEquals(defaultList.get(1).path, "path2/");
Assert.assertEquals(defaultList.get(1).allParams.size(), 1);
}
@Test
public void testRefModelValidationProperties(){
public void testRefModelValidationProperties() {
OpenAPI openAPI = TestUtils.parseFlattenSpec("src/test/resources/2_0/refAliasedPrimitiveWithValidation.yml");
ClientOptInput opts = new ClientOptInput();
opts.setOpenAPI(openAPI);
@ -119,34 +430,7 @@ public class DefaultGeneratorTest {
ApiResponse response = operation.getResponses().get("200");
CodegenResponse codegenResponse = config.fromResponse("200", response);
Assert.assertEquals(((Schema)codegenResponse.schema).getPattern(), expectedPattern);
Assert.assertEquals(((Schema) codegenResponse.schema).getPattern(), expectedPattern);
Assert.assertEquals(codegenResponse.pattern, escapedPattern);
}
@Test
public void minimalUpdateTest() throws IOException {
OpenAPI openAPI = TestUtils.createOpenAPI();
ClientOptInput opts = new ClientOptInput();
opts.setOpenAPI(openAPI);
DefaultCodegen codegen = new DefaultCodegen();
codegen.setEnableMinimalUpdate(true);
opts.setConfig(codegen);
DefaultGenerator generator = new DefaultGenerator();
generator.opts(opts);
File testPath = new File("temp/overwrite.test");
if (testPath.exists()) {
testPath.delete();
}
generator.writeToFile(testPath.toString(), "some file contents");
long createTime = testPath.lastModified();
try {
Thread.sleep(100);
} catch (InterruptedException ex) {
}
generator.writeToFile(testPath.toString(), "some file contents");
Assert.assertEquals(createTime, testPath.lastModified());
File testPathTmp = new File("temp/overwrite.test.tmp");
Assert.assertFalse(testPathTmp.exists());
testPath.delete();
}
}

View File

@ -15,43 +15,24 @@
*/
package org.openapitools.codegen;
import org.openapitools.codegen.templating.TemplateManagerOptions;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
/**
* Decorates {@link DefaultCodegen and tracks some internal calls}.
*
* @deprecated Please avoid using this type, as it is not a mock and invokes real generation. Prefer {@link DefaultGenerator#DefaultGenerator(Boolean)} with dryRun=true and/or true mocked spies.
*/
@Deprecated
public class MockDefaultGenerator extends DefaultGenerator {
public static final String INPUT_STREAM_CONTENT = "INPUT STREAM CONTENT";
private List<WrittenTemplateBasedFile> templateBasedFiles = new ArrayList<>();
private Map<String, String> files = new HashMap<>();
@Override
protected File processTemplateToFile(Map<String, Object> templateData, String templateName, String outputFilename) throws IOException {
templateBasedFiles.add(new WrittenTemplateBasedFile(templateData, templateName, normalizePath(outputFilename)));
return super.processTemplateToFile(templateData, templateName, outputFilename);
}
@Override
protected File writeInputStreamToFile(String filename, InputStream in, String templateFile) throws FileNotFoundException, IOException {
files.put(normalizePath(filename), INPUT_STREAM_CONTENT + ": from template '" + templateFile + "'");
return new File(filename);
}
@Override
public File writeToFile(String filename, String contents) throws IOException {
files.put(normalizePath(filename), contents);
return new File(filename);
}
private String normalizePath(String filename) {
return filename.replace("\\", "/").replace("//", "/");
}
public List<WrittenTemplateBasedFile> getTemplateBasedFiles() {
return templateBasedFiles;
}
@ -60,6 +41,26 @@ public class MockDefaultGenerator extends DefaultGenerator {
return files;
}
// public static final String INPUT_STREAM_CONTENT = "INPUT STREAM CONTENT";
private List<WrittenTemplateBasedFile> templateBasedFiles = new ArrayList<>();
private Map<String, String> files = new HashMap<>();
public MockDefaultGenerator() {
super(true);
}
public MockDefaultGenerator(boolean dryRun) {
super(dryRun);
}
@Override
public Generator opts(ClientOptInput opts) {
Generator o = super.opts(opts);
TemplateManagerOptions templateManagerOptions = new TemplateManagerOptions(this.config.isEnableMinimalUpdate(),this.config.isSkipOverwrite());
this.templateProcessor = new ObservableDryRunTemplateManager(templateManagerOptions);
return o;
}
public static class WrittenTemplateBasedFile {
private Map<String, Object> templateData;
private String templateName;
@ -91,4 +92,34 @@ public class MockDefaultGenerator extends DefaultGenerator {
"templateData=" + templateData + "]";
}
}
class ObservableDryRunTemplateManager extends DryRunTemplateManager {
public ObservableDryRunTemplateManager(TemplateManagerOptions options) {
super(options);
}
private String normalizePath(String filename) {
return filename.replace("\\", "/").replace("//", "/");
}
@Override
public File write(Map<String, Object> data, String template, File target) throws IOException {
String filename = normalizePath(target.toPath().normalize().toString());
templateBasedFiles.add(new WrittenTemplateBasedFile(data, template, filename));
File file = super.write(data, template, target);
if (file != null && file.exists()) {
byte[] contents = Files.readAllBytes(file.toPath());
files.put(normalizePath(filename), new String(contents, StandardCharsets.UTF_8));
}
return file;
}
@Override
public File writeToFile(String filename, byte[] contents) throws IOException {
files.put(normalizePath(filename), new String(contents, StandardCharsets.UTF_8));
return super.writeToFile(filename, contents);
}
}
}

View File

@ -0,0 +1,189 @@
package org.openapitools.codegen;
import org.openapitools.codegen.api.TemplatePathLocator;
import org.openapitools.codegen.templating.HandlebarsEngineAdapter;
import org.openapitools.codegen.templating.MustacheEngineAdapter;
import org.openapitools.codegen.templating.TemplateManagerOptions;
import org.testng.annotations.Test;
import java.io.File;
import java.io.IOException;
import java.io.InputStreamReader;
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.Arrays;
import java.util.HashMap;
import java.util.Map;
import static org.testng.Assert.*;
@SuppressWarnings("ResultOfMethodCallIgnored")
public class TemplateManagerTest {
static class ResourceTemplateLoader implements TemplatePathLocator {
/**
* Get the full path to a relative template file.
*
* @param relativeTemplateFile Template file
* @return String Full template file path
*/
@Override
public String getFullTemplatePath(String relativeTemplateFile) {
return Paths.get("templating","templates", relativeTemplateFile).toString();
}
}
private final HandlebarsEngineAdapter handlebarsEngineAdapter = new HandlebarsEngineAdapter();
private final MustacheEngineAdapter mustacheEngineAdapter = new MustacheEngineAdapter();
private final TemplatePathLocator locator = new ResourceTemplateLoader();
@Test
public void loadTemplateContents(){
TemplateManagerOptions opts = new TemplateManagerOptions(false,false);
TemplateManager manager = new TemplateManager(opts, mustacheEngineAdapter, new TemplatePathLocator[]{ locator });
assertEquals(manager.getFullTemplateContents("simple.mustache"), "{{name}} and {{age}}");
}
@Test
public void readTemplate(){
TemplateManagerOptions opts = new TemplateManagerOptions(false,false);
TemplateManager manager = new TemplateManager(opts, mustacheEngineAdapter, new TemplatePathLocator[]{ locator });
assertEquals(manager.readTemplate("templating/templates/simple.mustache"), "{{name}} and {{age}}");
}
@Test
public void loadTemplatePath(){
TemplateManagerOptions opts = new TemplateManagerOptions(false,false);
TemplateManager manager = new TemplateManager(opts, mustacheEngineAdapter, new TemplatePathLocator[]{ locator });
assertEquals(manager.getFullTemplatePath("simple.mustache"), Paths.get("templating/templates/simple.mustache"));
}
@Test
public void getTemplateReader(){
TemplateManagerOptions opts = new TemplateManagerOptions(false,false);
TemplateManager manager = new TemplateManager(opts, mustacheEngineAdapter, new TemplatePathLocator[]{ locator });
assertTrue(manager.getTemplateReader("templating/templates/simple.mustache") instanceof InputStreamReader);
}
@Test
public void writeViaMustacheAdapter() throws IOException {
TemplateManagerOptions opts = new TemplateManagerOptions(false,false);
TemplateManager manager = new TemplateManager(opts, mustacheEngineAdapter, new TemplatePathLocator[]{ locator });
Map<String, Object> data = new HashMap<>();
data.put("name","Teddy");
data.put("age", "3");
Path target = Files.createTempDirectory("test-templatemanager");
try {
File output = new File(target.toFile(), "simple.txt");
File written = manager.write(data, "simple.mustache", output);
assertEquals(Files.readAllLines(written.toPath()).get(0), "Teddy and 3");
} finally {
target.toFile().delete();
}
}
@Test
public void skipOverwriteViaOption() throws IOException {
TemplateManagerOptions opts = new TemplateManagerOptions(false,true);
TemplateManager manager = new TemplateManager(opts, mustacheEngineAdapter, new TemplatePathLocator[]{ locator });
Map<String, Object> data = new HashMap<>();
data.put("name","Teddy");
data.put("age", "3");
Path target = Files.createTempDirectory("test-templatemanager");
try {
File output = new File(target.toFile(), "simple.txt");
Files.write(output.toPath(), "original data".getBytes(StandardCharsets.UTF_8));
File written = manager.write(data, "simple.mustache", output);
assertEquals(Files.readAllLines(written.toPath()).get(0), "original data");
} finally {
target.toFile().delete();
}
}
@Test
public void minimalUpdateOnlyWritesChangedContents() throws IOException {
TemplateManagerOptions opts = new TemplateManagerOptions(true,false);
TemplateManager manager = new TemplateManager(opts, mustacheEngineAdapter, new TemplatePathLocator[]{ locator });
Map<String, Object> data = new HashMap<>();
data.put("name","Teddy");
data.put("age", "3");
Path target = Files.createTempDirectory("test-templatemanager");
try {
File output = new File(target.toFile(), "simple.txt");
Files.write(output.toPath(), "original data".getBytes(StandardCharsets.UTF_8));
long originalModified = output.lastModified();
Thread.sleep(1000L);
File written = manager.write(data, "simple.mustache", output);
long firstWriteModified = written.lastModified();
assertNotEquals(firstWriteModified, originalModified);
// sanity check here.
assertEquals(Files.readAllLines(written.toPath()).get(0), "Teddy and 3");
File rewritten = manager.write(data, "simple.mustache", output);
long lastModified = rewritten.lastModified();
assertEquals(lastModified, firstWriteModified);
} catch (InterruptedException e) {
e.printStackTrace();
} finally {
target.toFile().delete();
}
}
@Test
public void overwritesWhenSkipOverwriteFalse() throws IOException {
TemplateManagerOptions opts = new TemplateManagerOptions(false,false);
TemplateManager manager = new TemplateManager(opts, mustacheEngineAdapter, new TemplatePathLocator[]{ locator });
Map<String, Object> data = new HashMap<>();
data.put("name","Teddy");
data.put("age", "3");
Path target = Files.createTempDirectory("test-templatemanager");
try {
File output = new File(target.toFile(), "simple.txt");
Files.write(output.toPath(), "original data".getBytes(StandardCharsets.UTF_8));
File written = manager.write(data, "simple.mustache", output);
assertEquals(Files.readAllLines(written.toPath()).get(0), "Teddy and 3");
} finally {
target.toFile().delete();
}
}
@Test
public void writeViaHandlebarsAdapter() throws IOException {
TemplateManagerOptions opts = new TemplateManagerOptions(false,false);
TemplateManager manager = new TemplateManager(opts, handlebarsEngineAdapter, new TemplatePathLocator[]{ locator });
Map<String, Object> data = new HashMap<>();
data.put("name", "Jack");
data.put("numbers", Arrays.asList(1, 2, 3, 4, 5));
Path target = Files.createTempDirectory("test-templatemanager");
try {
File output = new File(target.toFile(), "simple.txt");
File written = manager.write(data, "numbers.handlebars", output);
assertEquals(Files.readAllLines(written.toPath()).get(0), "Jack counts 1 2 3 4 5");
} finally {
target.toFile().delete();
}
}
}

View File

@ -22,7 +22,12 @@ import org.openapitools.codegen.utils.ModelUtils;
import org.testng.Assert;
import java.io.File;
import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.stream.Collectors;
@ -92,6 +97,17 @@ public class TestUtils {
return openAPI;
}
/**
* Extract file from {@link MockDefaultGenerator}
*
* @param generator Generator
* @param root root path
* @param filename filename under root
*
* @return a {@link WrittenTemplateBasedFile}
* @deprecated Since 5.0. Please avoid this method and usage of {@link MockDefaultGenerator}, prefer {@link DefaultGenerator#DefaultGenerator(Boolean)} with dryRun=true.
*/
@Deprecated
public static WrittenTemplateBasedFile getTemplateBasedFile(MockDefaultGenerator generator, File root, String filename) {
String defaultApiFilename = new File(root, filename).getAbsolutePath().replace("\\", "/");
Optional<WrittenTemplateBasedFile> optional = generator.getTemplateBasedFiles().stream().filter(f -> defaultApiFilename.equals(f.getOutputFilename())).findFirst();
@ -99,24 +115,14 @@ public class TestUtils {
return optional.get();
}
public static void ensureContainsFile(Map<String, String> generatedFiles, File root, String filename) {
File file = new File(root, filename);
String absoluteFilename = file.getAbsolutePath().replace("\\", "/");
if (!generatedFiles.containsKey(absoluteFilename)) {
fail("Could not find '" + absoluteFilename + "' file in list:\n" +
generatedFiles.keySet().stream().sorted().collect(Collectors.joining(",\n")));
}
assertTrue(generatedFiles.containsKey(absoluteFilename), "File '" + absoluteFilename + "' was not found in the list of generated files");
public static void ensureContainsFile(List<File> generatedFiles, File root, String filename) {
Path path = root.toPath().resolve(filename);
assertTrue(generatedFiles.contains(path.toFile()), "File '" + path.toAbsolutePath().toString() + "' was not found in the list of generated files");
}
public static void ensureDoesNotContainsFile(Map<String, String> generatedFiles, File root, String filename) {
File file = new File(root, filename);
String absoluteFilename = file.getAbsolutePath().replace("\\", "/");
if (generatedFiles.containsKey(absoluteFilename)) {
fail("File '" + absoluteFilename + "' exists in file in list:\n" +
generatedFiles.keySet().stream().sorted().collect(Collectors.joining(",\n")));
}
assertFalse(generatedFiles.containsKey(absoluteFilename), "File '" + absoluteFilename + "' was found in the list of generated files");
public static void ensureDoesNotContainsFile(List<File> generatedFiles, File root, String filename) {
Path path = root.toPath().resolve(filename);
assertFalse(generatedFiles.contains(path.toFile()), "File '" + path.toAbsolutePath().toString() + "' was found in the list of generated files");
}
public static void validateJavaSourceFiles(Map<String, String> fileMap) {
@ -128,6 +134,22 @@ public class TestUtils {
);
}
public static void validateJavaSourceFiles(List<File> files) {
files.forEach( f -> {
String fileName = f.getName();
if (fileName.endsWith(".java")) {
String fileContents = "";
try {
fileContents = new String(Files.readAllBytes(f.toPath()), StandardCharsets.UTF_8);
} catch (IOException ignored) {
}
assertValidJavaSourceCode(fileContents, fileName);
}
}
);
}
public static void assertValidJavaSourceCode(String javaSourceCode, String filename) {
try {
CompilationUnit compilation = StaticJavaParser.parse(javaSourceCode);
@ -138,24 +160,30 @@ public class TestUtils {
}
}
public static void assertFileContains(MockDefaultGenerator generator, String path, String... lines) {
final String generatedFile = generator.getFiles().get(path);
if (null == generatedFile) {
fail("File " + path + " not found in " + generator.getFiles().keySet());
public static void assertFileContains(Path path, String... lines) {
try {
String generatedFile = new String(Files.readAllBytes(path), StandardCharsets.UTF_8);
String file = linearize(generatedFile);
assertNotNull(file);
for (String line : lines)
assertTrue(file.contains(linearize(line)));
} catch (IOException e) {
fail("Unable to evaluate file " + path.toString());
}
String file = linearize(generatedFile);
assertNotNull(file);
for (String line : lines)
assertTrue(file.contains(linearize(line)));
}
private static String linearize(String target) {
return target.replaceAll("\r?\n", "").replaceAll("\\s+", "\\s");
}
public static void assertFileNotContains(MockDefaultGenerator generator, String path, String... lines) {
String file = linearize(generator.getFiles().get(path));
public static void assertFileNotContains(Path path, String... lines) {
String generatedFile = null;
try {
generatedFile = new String(Files.readAllBytes(path), StandardCharsets.UTF_8);
} catch (IOException e) {
fail("Unable to evaluate file " + path.toString());
}
String file = linearize(generatedFile);
assertNotNull(file);
for (String line : lines)
assertFalse(file.contains(linearize(line)));

View File

@ -48,10 +48,9 @@ public class AsciidocGeneratorTest {
.addAdditionalProperty(AsciidocDocumentationCodegen.SPEC_DIR, "MY-SPEC-DIR");
final ClientOptInput clientOptInput = configurator.toClientOptInput();
MockDefaultGenerator generator = new MockDefaultGenerator();
generator.opts(clientOptInput).generate();
Map<String, String> generatedFiles = generator.getFiles();
DefaultGenerator generator = new DefaultGenerator();
generator.setGenerateMetadata(false);
List<File> generatedFiles = generator.opts(clientOptInput).generate();
TestUtils.ensureContainsFile(generatedFiles, output, "index.adoc");
}

View File

@ -22,10 +22,13 @@ import static org.testng.Assert.assertNotNull;
import java.io.File;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.util.Arrays;
import org.openapitools.codegen.ClientOptInput;
import org.openapitools.codegen.DefaultGenerator;
import org.openapitools.codegen.MockDefaultGenerator;
import org.openapitools.codegen.TestUtils;
import org.openapitools.codegen.languages.HaskellServantCodegen;
import org.testng.annotations.Test;
@ -54,18 +57,11 @@ public class HaskellServantCodegenTest {
input.setConfig(codegen);
// when
MockDefaultGenerator generator = new MockDefaultGenerator();
DefaultGenerator generator = new DefaultGenerator();
generator.setGenerateMetadata(false);
generator.opts(input).generate();
// then
assertFileNotContains(generator, outputPath + "/lib/RootOperation/API.hs", "\"\" :>");
}
private static void assertFileNotContains(MockDefaultGenerator generator, String file, String... expected) {
String content = generator.getFiles().get(file);
assertNotNull(content, "The file \"" + file + "\" was not generated");
for (String line : expected) {
assertFalse(content.contains(line), "The file \"" + file + "\" contains \"" + line + "\"");
}
TestUtils.assertFileNotContains(Paths.get(outputPath + "/lib/RootOperation/API.hs"), "\"\" :>");
}
}

View File

@ -35,7 +35,10 @@ import org.testng.annotations.Test;
import java.io.File;
import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.*;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
@ -263,59 +266,52 @@ public class JavaClientCodegenTest {
.setOutputDir(output.getAbsolutePath().replace("\\", "/"));
final ClientOptInput clientOptInput = configurator.toClientOptInput();
MockDefaultGenerator generator = new MockDefaultGenerator();
generator.opts(clientOptInput).generate();
DefaultGenerator generator = new DefaultGenerator();
List<File> files = generator.opts(clientOptInput).generate();
Map<String, String> generatedFiles = generator.getFiles();
Assert.assertEquals(generatedFiles.size(), 37);
TestUtils.ensureContainsFile(generatedFiles, output, ".gitignore");
TestUtils.ensureContainsFile(generatedFiles, output, ".openapi-generator-ignore");
TestUtils.ensureContainsFile(generatedFiles, output, ".openapi-generator/VERSION");
TestUtils.ensureContainsFile(generatedFiles, output, ".travis.yml");
TestUtils.ensureContainsFile(generatedFiles, output, "build.gradle");
TestUtils.ensureContainsFile(generatedFiles, output, "build.sbt");
TestUtils.ensureContainsFile(generatedFiles, output, "docs/DefaultApi.md");
TestUtils.ensureContainsFile(generatedFiles, output, "git_push.sh");
TestUtils.ensureContainsFile(generatedFiles, output, "gradle.properties");
TestUtils.ensureContainsFile(generatedFiles, output, "gradle/wrapper/gradle-wrapper.jar");
TestUtils.ensureContainsFile(generatedFiles, output, "gradle/wrapper/gradle-wrapper.properties");
TestUtils.ensureContainsFile(generatedFiles, output, "gradlew.bat");
TestUtils.ensureContainsFile(generatedFiles, output, "gradlew");
TestUtils.ensureContainsFile(generatedFiles, output, "pom.xml");
TestUtils.ensureContainsFile(generatedFiles, output, "README.md");
TestUtils.ensureContainsFile(generatedFiles, output, "settings.gradle");
TestUtils.ensureContainsFile(generatedFiles, output, "api/openapi.yaml");
TestUtils.ensureContainsFile(generatedFiles, output, "src/main/AndroidManifest.xml");
TestUtils.ensureContainsFile(generatedFiles, output, "src/main/java/xyz/abcdef/api/DefaultApi.java");
TestUtils.ensureContainsFile(generatedFiles, output, "src/main/java/xyz/abcdef/ApiCallback.java");
TestUtils.ensureContainsFile(generatedFiles, output, "src/main/java/xyz/abcdef/ApiClient.java");
TestUtils.ensureContainsFile(generatedFiles, output, "src/main/java/xyz/abcdef/ApiException.java");
TestUtils.ensureContainsFile(generatedFiles, output, "src/main/java/xyz/abcdef/ApiResponse.java");
TestUtils.ensureContainsFile(generatedFiles, output, "src/main/java/xyz/abcdef/ServerConfiguration.java");
TestUtils.ensureContainsFile(generatedFiles, output, "src/main/java/xyz/abcdef/ServerVariable.java");
TestUtils.ensureContainsFile(generatedFiles, output, "src/main/java/xyz/abcdef/auth/Authentication.java");
TestUtils.ensureContainsFile(generatedFiles, output, "src/main/java/xyz/abcdef/auth/ApiKeyAuth.java");
TestUtils.ensureContainsFile(generatedFiles, output, "src/main/java/xyz/abcdef/auth/HttpBasicAuth.java");
TestUtils.ensureContainsFile(generatedFiles, output, "src/main/java/xyz/abcdef/auth/HttpBearerAuth.java");
//TestUtils.ensureContainsFile(generatedFiles, output, "src/main/java/xyz/abcdef/auth/OAuth.java");
//TestUtils.ensureContainsFile(generatedFiles, output, "src/main/java/xyz/abcdef/auth/OAuthFlow.java");
TestUtils.ensureContainsFile(generatedFiles, output, "src/main/java/xyz/abcdef/Configuration.java");
TestUtils.ensureContainsFile(generatedFiles, output, "src/main/java/xyz/abcdef/GzipRequestInterceptor.java");
TestUtils.ensureContainsFile(generatedFiles, output, "src/main/java/xyz/abcdef/JSON.java");
TestUtils.ensureContainsFile(generatedFiles, output, "src/main/java/xyz/abcdef/Pair.java");
TestUtils.ensureContainsFile(generatedFiles, output, "src/main/java/xyz/abcdef/ProgressRequestBody.java");
TestUtils.ensureContainsFile(generatedFiles, output, "src/main/java/xyz/abcdef/ProgressResponseBody.java");
TestUtils.ensureContainsFile(generatedFiles, output, "src/main/java/xyz/abcdef/StringUtil.java");
TestUtils.ensureContainsFile(generatedFiles, output, "src/test/java/xyz/abcdef/api/DefaultApiTest.java");
Assert.assertEquals(files.size(), 38);
TestUtils.ensureContainsFile(files, output, ".gitignore");
TestUtils.ensureContainsFile(files, output, ".openapi-generator-ignore");
TestUtils.ensureContainsFile(files, output, ".openapi-generator/FILES");
TestUtils.ensureContainsFile(files, output, ".openapi-generator/VERSION");
TestUtils.ensureContainsFile(files, output, ".travis.yml");
TestUtils.ensureContainsFile(files, output, "build.gradle");
TestUtils.ensureContainsFile(files, output, "build.sbt");
TestUtils.ensureContainsFile(files, output, "docs/DefaultApi.md");
TestUtils.ensureContainsFile(files, output, "git_push.sh");
TestUtils.ensureContainsFile(files, output, "gradle.properties");
TestUtils.ensureContainsFile(files, output, "gradle/wrapper/gradle-wrapper.jar");
TestUtils.ensureContainsFile(files, output, "gradle/wrapper/gradle-wrapper.properties");
TestUtils.ensureContainsFile(files, output, "gradlew.bat");
TestUtils.ensureContainsFile(files, output, "gradlew");
TestUtils.ensureContainsFile(files, output, "pom.xml");
TestUtils.ensureContainsFile(files, output, "README.md");
TestUtils.ensureContainsFile(files, output, "settings.gradle");
TestUtils.ensureContainsFile(files, output, "api/openapi.yaml");
TestUtils.ensureContainsFile(files, output, "src/main/AndroidManifest.xml");
TestUtils.ensureContainsFile(files, output, "src/main/java/xyz/abcdef/api/DefaultApi.java");
TestUtils.ensureContainsFile(files, output, "src/main/java/xyz/abcdef/ApiCallback.java");
TestUtils.ensureContainsFile(files, output, "src/main/java/xyz/abcdef/ApiClient.java");
TestUtils.ensureContainsFile(files, output, "src/main/java/xyz/abcdef/ApiException.java");
TestUtils.ensureContainsFile(files, output, "src/main/java/xyz/abcdef/ApiResponse.java");
TestUtils.ensureContainsFile(files, output, "src/main/java/xyz/abcdef/ServerConfiguration.java");
TestUtils.ensureContainsFile(files, output, "src/main/java/xyz/abcdef/ServerVariable.java");
TestUtils.ensureContainsFile(files, output, "src/main/java/xyz/abcdef/auth/ApiKeyAuth.java");
TestUtils.ensureContainsFile(files, output, "src/main/java/xyz/abcdef/auth/Authentication.java");
TestUtils.ensureContainsFile(files, output, "src/main/java/xyz/abcdef/auth/HttpBasicAuth.java");
TestUtils.ensureContainsFile(files, output, "src/main/java/xyz/abcdef/auth/HttpBearerAuth.java");
TestUtils.ensureContainsFile(files, output, "src/main/java/xyz/abcdef/Configuration.java");
TestUtils.ensureContainsFile(files, output, "src/main/java/xyz/abcdef/GzipRequestInterceptor.java");
TestUtils.ensureContainsFile(files, output, "src/main/java/xyz/abcdef/JSON.java");
TestUtils.ensureContainsFile(files, output, "src/main/java/xyz/abcdef/Pair.java");
TestUtils.ensureContainsFile(files, output, "src/main/java/xyz/abcdef/ProgressRequestBody.java");
TestUtils.ensureContainsFile(files, output, "src/main/java/xyz/abcdef/ProgressResponseBody.java");
TestUtils.ensureContainsFile(files, output, "src/main/java/xyz/abcdef/StringUtil.java");
TestUtils.ensureContainsFile(files, output, "src/test/java/xyz/abcdef/api/DefaultApiTest.java");
validateJavaSourceFiles(generatedFiles);
validateJavaSourceFiles(files);
String defaultApiFilename = new File(output, "src/main/java/xyz/abcdef/api/DefaultApi.java").getAbsolutePath().replace("\\", "/");
String defaultApiConent = generatedFiles.get(defaultApiFilename);
assertTrue(defaultApiConent.contains("public class DefaultApi"));
WrittenTemplateBasedFile templateBasedFile = TestUtils.getTemplateBasedFile(generator, output, "src/main/java/xyz/abcdef/api/DefaultApi.java");
Assert.assertEquals(templateBasedFile.getTemplateData().get("classname"), "DefaultApi");
TestUtils.assertFileContains(Paths.get(output + "/src/main/java/xyz/abcdef/api/DefaultApi.java"), "public class DefaultApi");
output.deleteOnExit();
}
@ -339,58 +335,57 @@ public class JavaClientCodegenTest {
.setOutputDir(output.getAbsolutePath().replace("\\", "/"));
final ClientOptInput clientOptInput = configurator.toClientOptInput();
MockDefaultGenerator generator = new MockDefaultGenerator();
generator.opts(clientOptInput).generate();
DefaultGenerator generator = new DefaultGenerator();
List<File> files = generator.opts(clientOptInput).generate();
Map<String, String> generatedFiles = generator.getFiles();
Assert.assertEquals(generatedFiles.size(), 40);
TestUtils.ensureContainsFile(generatedFiles, output, ".gitignore");
TestUtils.ensureContainsFile(generatedFiles, output, ".openapi-generator-ignore");
TestUtils.ensureContainsFile(generatedFiles, output, ".openapi-generator/VERSION");
TestUtils.ensureContainsFile(generatedFiles, output, ".travis.yml");
TestUtils.ensureContainsFile(generatedFiles, output, "build.gradle");
TestUtils.ensureContainsFile(generatedFiles, output, "build.sbt");
TestUtils.ensureContainsFile(generatedFiles, output, "docs/PingApi.md");
TestUtils.ensureContainsFile(generatedFiles, output, "docs/SomeObj.md");
TestUtils.ensureContainsFile(generatedFiles, output, "git_push.sh");
TestUtils.ensureContainsFile(generatedFiles, output, "gradle.properties");
TestUtils.ensureContainsFile(generatedFiles, output, "gradle/wrapper/gradle-wrapper.jar");
TestUtils.ensureContainsFile(generatedFiles, output, "gradle/wrapper/gradle-wrapper.properties");
TestUtils.ensureContainsFile(generatedFiles, output, "gradlew.bat");
TestUtils.ensureContainsFile(generatedFiles, output, "gradlew");
TestUtils.ensureContainsFile(generatedFiles, output, "pom.xml");
TestUtils.ensureContainsFile(generatedFiles, output, "README.md");
TestUtils.ensureContainsFile(generatedFiles, output, "settings.gradle");
TestUtils.ensureContainsFile(generatedFiles, output, "api/openapi.yaml");
TestUtils.ensureContainsFile(generatedFiles, output, "src/main/AndroidManifest.xml");
TestUtils.ensureContainsFile(generatedFiles, output, "src/main/java/zz/yyyy/api/xxxx/PingApi.java");
TestUtils.ensureContainsFile(generatedFiles, output, "src/main/java/zz/yyyy/invoker/xxxx/ApiCallback.java");
TestUtils.ensureContainsFile(generatedFiles, output, "src/main/java/zz/yyyy/invoker/xxxx/ApiClient.java");
TestUtils.ensureContainsFile(generatedFiles, output, "src/main/java/zz/yyyy/invoker/xxxx/ApiException.java");
TestUtils.ensureContainsFile(generatedFiles, output, "src/main/java/zz/yyyy/invoker/xxxx/ApiResponse.java");
TestUtils.ensureContainsFile(generatedFiles, output, "src/main/java/zz/yyyy/invoker/xxxx/ServerConfiguration.java");
TestUtils.ensureContainsFile(generatedFiles, output, "src/main/java/zz/yyyy/invoker/xxxx/ServerVariable.java");
TestUtils.ensureContainsFile(generatedFiles, output, "src/main/java/zz/yyyy/invoker/xxxx/auth/Authentication.java");
TestUtils.ensureContainsFile(generatedFiles, output, "src/main/java/zz/yyyy/invoker/xxxx/auth/ApiKeyAuth.java");
TestUtils.ensureContainsFile(generatedFiles, output, "src/main/java/zz/yyyy/invoker/xxxx/auth/HttpBasicAuth.java");
TestUtils.ensureContainsFile(generatedFiles, output, "src/main/java/zz/yyyy/invoker/xxxx/auth/HttpBearerAuth.java");
TestUtils.ensureContainsFile(generatedFiles, output, "src/main/java/zz/yyyy/invoker/xxxx/Configuration.java");
TestUtils.ensureContainsFile(generatedFiles, output, "src/main/java/zz/yyyy/invoker/xxxx/GzipRequestInterceptor.java");
TestUtils.ensureContainsFile(generatedFiles, output, "src/main/java/zz/yyyy/invoker/xxxx/JSON.java");
TestUtils.ensureContainsFile(generatedFiles, output, "src/main/java/zz/yyyy/invoker/xxxx/Pair.java");
TestUtils.ensureContainsFile(generatedFiles, output, "src/main/java/zz/yyyy/invoker/xxxx/ProgressRequestBody.java");
TestUtils.ensureContainsFile(generatedFiles, output, "src/main/java/zz/yyyy/invoker/xxxx/ProgressResponseBody.java");
TestUtils.ensureContainsFile(generatedFiles, output, "src/main/java/zz/yyyy/invoker/xxxx/StringUtil.java");
TestUtils.ensureContainsFile(generatedFiles, output, "src/main/java/zz/yyyy/model/xxxx/SomeObj.java");
TestUtils.ensureContainsFile(generatedFiles, output, "src/test/java/zz/yyyy/api/xxxx/PingApiTest.java");
TestUtils.ensureContainsFile(generatedFiles, output, "src/test/java/zz/yyyy/model/xxxx/SomeObjTest.java");
Assert.assertEquals(files.size(), 41);
TestUtils.ensureContainsFile(files, output, ".gitignore");
TestUtils.ensureContainsFile(files, output, ".openapi-generator-ignore");
TestUtils.ensureContainsFile(files, output, ".openapi-generator/FILES");
TestUtils.ensureContainsFile(files, output, ".openapi-generator/VERSION");
TestUtils.ensureContainsFile(files, output, ".travis.yml");
TestUtils.ensureContainsFile(files, output, "build.gradle");
TestUtils.ensureContainsFile(files, output, "build.sbt");
TestUtils.ensureContainsFile(files, output, "docs/PingApi.md");
TestUtils.ensureContainsFile(files, output, "docs/SomeObj.md");
TestUtils.ensureContainsFile(files, output, "git_push.sh");
TestUtils.ensureContainsFile(files, output, "gradle.properties");
TestUtils.ensureContainsFile(files, output, "gradle/wrapper/gradle-wrapper.jar");
TestUtils.ensureContainsFile(files, output, "gradle/wrapper/gradle-wrapper.properties");
TestUtils.ensureContainsFile(files, output, "gradlew.bat");
TestUtils.ensureContainsFile(files, output, "gradlew");
TestUtils.ensureContainsFile(files, output, "pom.xml");
TestUtils.ensureContainsFile(files, output, "README.md");
TestUtils.ensureContainsFile(files, output, "settings.gradle");
TestUtils.ensureContainsFile(files, output, "api/openapi.yaml");
TestUtils.ensureContainsFile(files, output, "src/main/AndroidManifest.xml");
TestUtils.ensureContainsFile(files, output, "src/main/java/zz/yyyy/api/xxxx/PingApi.java");
TestUtils.ensureContainsFile(files, output, "src/main/java/zz/yyyy/invoker/xxxx/ApiCallback.java");
TestUtils.ensureContainsFile(files, output, "src/main/java/zz/yyyy/invoker/xxxx/ApiClient.java");
TestUtils.ensureContainsFile(files, output, "src/main/java/zz/yyyy/invoker/xxxx/ApiException.java");
TestUtils.ensureContainsFile(files, output, "src/main/java/zz/yyyy/invoker/xxxx/ApiResponse.java");
TestUtils.ensureContainsFile(files, output, "src/main/java/zz/yyyy/invoker/xxxx/ServerConfiguration.java");
TestUtils.ensureContainsFile(files, output, "src/main/java/zz/yyyy/invoker/xxxx/ServerVariable.java");
TestUtils.ensureContainsFile(files, output, "src/main/java/zz/yyyy/invoker/xxxx/auth/ApiKeyAuth.java");
TestUtils.ensureContainsFile(files, output, "src/main/java/zz/yyyy/invoker/xxxx/auth/Authentication.java");
TestUtils.ensureContainsFile(files, output, "src/main/java/zz/yyyy/invoker/xxxx/auth/HttpBasicAuth.java");
TestUtils.ensureContainsFile(files, output, "src/main/java/zz/yyyy/invoker/xxxx/auth/HttpBearerAuth.java");
TestUtils.ensureContainsFile(files, output, "src/main/java/zz/yyyy/invoker/xxxx/Configuration.java");
TestUtils.ensureContainsFile(files, output, "src/main/java/zz/yyyy/invoker/xxxx/GzipRequestInterceptor.java");
TestUtils.ensureContainsFile(files, output, "src/main/java/zz/yyyy/invoker/xxxx/JSON.java");
TestUtils.ensureContainsFile(files, output, "src/main/java/zz/yyyy/invoker/xxxx/Pair.java");
TestUtils.ensureContainsFile(files, output, "src/main/java/zz/yyyy/invoker/xxxx/ProgressRequestBody.java");
TestUtils.ensureContainsFile(files, output, "src/main/java/zz/yyyy/invoker/xxxx/ProgressResponseBody.java");
TestUtils.ensureContainsFile(files, output, "src/main/java/zz/yyyy/invoker/xxxx/StringUtil.java");
TestUtils.ensureContainsFile(files, output, "src/main/java/zz/yyyy/model/xxxx/SomeObj.java");
TestUtils.ensureContainsFile(files, output, "src/test/java/zz/yyyy/api/xxxx/PingApiTest.java");
TestUtils.ensureContainsFile(files, output, "src/test/java/zz/yyyy/model/xxxx/SomeObjTest.java");
validateJavaSourceFiles(generatedFiles);
validateJavaSourceFiles(files);
String defaultApiFilename = new File(output, "src/main/java/zz/yyyy/model/xxxx/SomeObj.java").getAbsolutePath().replace("\\", "/");
String defaultApiConent = generatedFiles.get(defaultApiFilename);
assertTrue(defaultApiConent.contains("public class SomeObj"));
assertTrue(defaultApiConent.contains("Boolean isActive()"));
TestUtils.assertFileContains(Paths.get(output + "/src/main/java/zz/yyyy/model/xxxx/SomeObj.java"),
"public class SomeObj",
"Boolean isActive()");
output.deleteOnExit();
}
@ -412,25 +407,22 @@ public class JavaClientCodegenTest {
.setOutputDir(output.getAbsolutePath().replace("\\", "/"));
final ClientOptInput clientOptInput = configurator.toClientOptInput();
MockDefaultGenerator generator = new MockDefaultGenerator();
generator.opts(clientOptInput).generate();
DefaultGenerator generator = new DefaultGenerator();
List<File> files = generator.opts(clientOptInput).generate();
Map<String, String> generatedFiles = generator.getFiles();
Assert.assertEquals(generatedFiles.size(), 26);
validateJavaSourceFiles(generatedFiles);
Assert.assertEquals(files.size(), 27);
validateJavaSourceFiles(files);
String defaultApiFilename = new File(output, "src/main/java/xyz/abcdef/api/DefaultApi.java").getAbsolutePath().replace("\\", "/");
String defaultApiContent = generatedFiles.get(defaultApiFilename);
assertTrue(defaultApiContent.contains("public class DefaultApi"));
assertTrue(defaultApiContent.contains("import java.net.http.HttpClient;"));
assertTrue(defaultApiContent.contains("import java.net.http.HttpRequest;"));
assertTrue(defaultApiContent.contains("import java.net.http.HttpResponse;"));
TestUtils.assertFileContains(Paths.get(output + "/src/main/java/xyz/abcdef/api/DefaultApi.java"),
"public class DefaultApi",
"import java.net.http.HttpClient;",
"import java.net.http.HttpRequest;",
"import java.net.http.HttpResponse;");
String apiClientFilename = new File(output, "src/main/java/xyz/abcdef/ApiClient.java").getAbsolutePath().replace("\\", "/");
String apiClientContent = generatedFiles.get(apiClientFilename);
assertTrue(apiClientContent.contains("public class ApiClient"));
assertTrue(apiClientContent.contains("import java.net.http.HttpClient;"));
assertTrue(apiClientContent.contains("import java.net.http.HttpRequest;"));
TestUtils.assertFileContains(Paths.get(output + "/src/main/java/xyz/abcdef/ApiClient.java"),
"public class ApiClient",
"import java.net.http.HttpClient;",
"import java.net.http.HttpRequest;");
}
@Test
@ -451,25 +443,25 @@ public class JavaClientCodegenTest {
.setOutputDir(output.getAbsolutePath().replace("\\", "/"));
final ClientOptInput clientOptInput = configurator.toClientOptInput();
MockDefaultGenerator generator = new MockDefaultGenerator();
generator.opts(clientOptInput).generate();
DefaultGenerator generator = new DefaultGenerator();
List<File> files = generator.opts(clientOptInput).generate();
Map<String, String> generatedFiles = generator.getFiles();
Assert.assertEquals(generatedFiles.size(), 29);
validateJavaSourceFiles(generatedFiles);
String defaultApiFilename = new File(output, "src/main/java/xyz/abcdef/api/PingApi.java").getAbsolutePath().replace("\\", "/");
String defaultApiContent = generatedFiles.get(defaultApiFilename);
assertTrue(defaultApiContent.contains("public class PingApi"));
assertTrue(defaultApiContent.contains("import java.net.http.HttpClient;"));
assertTrue(defaultApiContent.contains("import java.net.http.HttpRequest;"));
assertTrue(defaultApiContent.contains("import java.net.http.HttpResponse;"));
assertTrue(defaultApiContent.contains("import java.util.concurrent.CompletableFuture;"));
Assert.assertEquals(files.size(), 30);
validateJavaSourceFiles(files);
String apiClientFilename = new File(output, "src/main/java/xyz/abcdef/ApiClient.java").getAbsolutePath().replace("\\", "/");
String apiClientContent = generatedFiles.get(apiClientFilename);
assertTrue(apiClientContent.contains("public class ApiClient"));
assertTrue(apiClientContent.contains("import java.net.http.HttpClient;"));
assertTrue(apiClientContent.contains("import java.net.http.HttpRequest;"));
Path defaultApi = Paths.get(output + "/src/main/java/xyz/abcdef/api/PingApi.java");
TestUtils.assertFileContains(defaultApi,
"public class PingApi",
"import java.net.http.HttpClient;",
"import java.net.http.HttpRequest;",
"import java.net.http.HttpResponse;",
"import java.util.concurrent.CompletableFuture;");
Path apiClient = Paths.get(output + "/src/main/java/xyz/abcdef/ApiClient.java");
TestUtils.assertFileContains(apiClient,
"public class ApiClient",
"import java.net.http.HttpClient;",
"import java.net.http.HttpRequest;");
}
@Test
@ -594,19 +586,25 @@ public class JavaClientCodegenTest {
final ClientOptInput clientOptInput = configurator.toClientOptInput();
Assert.assertEquals(clientOptInput.getConfig().importMapping().get("TypeAlias"), "foo.bar.TypeAlias");
MockDefaultGenerator generator = new MockDefaultGenerator();
DefaultGenerator generator = new DefaultGenerator();
generator.setGeneratorPropertyDefault(CodegenConstants.MODELS, "true");
generator.setGeneratorPropertyDefault(CodegenConstants.MODEL_TESTS, "false");
generator.setGeneratorPropertyDefault(CodegenConstants.MODEL_DOCS, "false");
generator.setGeneratorPropertyDefault(CodegenConstants.APIS, "false");
generator.setGeneratorPropertyDefault(CodegenConstants.SUPPORTING_FILES, "false");
generator.opts(clientOptInput).generate();
generator.setGenerateMetadata(false);
List<File> files = generator.opts(clientOptInput).generate();
Map<String, String> generatedFiles = generator.getFiles();
Assert.assertEquals(generatedFiles.size(), 1);
TestUtils.ensureContainsFile(generatedFiles, output, "src/main/java/org/openapitools/client/model/ParentType.java");
Assert.assertEquals(files.size(), 1);
TestUtils.ensureContainsFile(files, output, "src/main/java/org/openapitools/client/model/ParentType.java");
final String parentTypeContents = generatedFiles.values().iterator().next();
String parentTypeContents = "";
try {
File file = files.stream().filter(f -> f.getName().endsWith("ParentType.java")).findFirst().get();
parentTypeContents = new String(Files.readAllBytes(file.toPath()), StandardCharsets.UTF_8);
} catch (IOException ignored) {
}
final Pattern FIELD_PATTERN = Pattern.compile(".* private (.*?) typeAlias;.*", Pattern.DOTALL);
Matcher fieldMatcher = FIELD_PATTERN.matcher(parentTypeContents);

View File

@ -14,7 +14,11 @@ import org.testng.annotations.BeforeMethod;
import org.testng.annotations.Test;
import java.io.File;
import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.List;
import java.util.Map;
import java.util.regex.Pattern;
@ -186,14 +190,23 @@ public class JavaJAXRSCXFExtServerCodegenTest extends JavaJaxrsBaseTest {
codegen = new JavaCXFExtServerCodegenTester();
}
private void checkFile(MockDefaultGenerator generator, String path, boolean fileShouldExist, String... regexes) {
String file = generator.getFiles().get(path);
if (fileShouldExist)
assertNotNull(file);
else
assertNull(file);
private void checkFile(Path path, boolean fileShouldExist, String... regexes) {
if (!fileShouldExist) {
assertFalse(path.toFile().exists());
return;
}
assertTrue(path.toFile().exists());
String contents = null;
try {
contents = new String(Files.readAllBytes(path), StandardCharsets.UTF_8);
} catch (IOException e) {
fail("Unable to evaluate file contents");
}
for (String regex : regexes)
assertTrue(Pattern.compile(regex).matcher(file).find());
assertTrue(Pattern.compile(regex).matcher(contents).find());
}
@SuppressWarnings("unchecked")
@ -445,7 +458,7 @@ public class JavaJAXRSCXFExtServerCodegenTest extends JavaJaxrsBaseTest {
input.setOpenAPI(openAPI);
input.setConfig(codegen);
MockDefaultGenerator generator = new MockDefaultGenerator();
DefaultGenerator generator = new DefaultGenerator();
generator.opts(input).generate();
String reGetPetById = "(?s)(?m)public Pet getPetById\\(Long petId\\) \\{" // split
@ -454,7 +467,7 @@ public class JavaJAXRSCXFExtServerCodegenTest extends JavaJaxrsBaseTest {
+ ".*" // split
+ "return response;\\s+" // split
+ "\\}"; // split
checkFile(generator, outputPath + "/src/main/java/org/openapitools/api/impl/PetApiServiceImpl.java", true,
checkFile(Paths.get(outputPath + "/src/main/java/org/openapitools/api/impl/PetApiServiceImpl.java"), true,
reGetPetById);
String reFindPetsByStatusTest = "(?s)(?m)public void findPetsByStatusTest\\(\\) throws Exception \\{\\s+"
@ -465,12 +478,12 @@ public class JavaJAXRSCXFExtServerCodegenTest extends JavaJaxrsBaseTest {
+ ".*" // split
+ "validate\\(response\\);\\s+" // split
+ "\\}";
checkFile(generator, outputPath + "/src/test/java/org/openapitools/api/PetApiTest.java", true,
checkFile(Paths.get(outputPath + "/src/test/java/org/openapitools/api/PetApiTest.java"), true,
reFindPetsByStatusTest);
checkFile(generator, outputPath + "/src/main/resources/test-data.json", false);
checkFile(Paths.get(outputPath + "/src/main/resources/test-data.json"), false);
checkFile(generator, outputPath + "/test-data-control.json", false);
checkFile(Paths.get(outputPath + "/test-data-control.json"), false);
}
@Test()
@ -490,7 +503,7 @@ public class JavaJAXRSCXFExtServerCodegenTest extends JavaJaxrsBaseTest {
input.setOpenAPI(openAPI);
input.setConfig(codegen);
MockDefaultGenerator generator = new MockDefaultGenerator();
DefaultGenerator generator = new DefaultGenerator();
generator.opts(input).generate();
String reInitCache = "(?s)(?m)\\{\\s+" + "try \\{\\s+"
@ -499,7 +512,7 @@ public class JavaJAXRSCXFExtServerCodegenTest extends JavaJaxrsBaseTest {
String reGetPetById = "(?s)(?m)public Pet getPetById\\(Long petId\\) \\{.*" // split
+ "try \\{\\s*" // split
+ "Pet response = cache\\.getObject\\(\"/getPetById/response\", Pet\\.class\\);";
checkFile(generator, outputPath + "/src/main/java/org/openapitools/api/impl/PetApiServiceImpl.java", true,
checkFile(Paths.get(outputPath + "/src/main/java/org/openapitools/api/impl/PetApiServiceImpl.java"), true,
reInitCache, reGetPetById);
reInitCache = "(?s)(?m)public static void beforeClass\\(\\) throws Exception \\{\\s+"
@ -509,12 +522,12 @@ public class JavaJAXRSCXFExtServerCodegenTest extends JavaJaxrsBaseTest {
+ "\\.child\\(\"/org\\.openapitools\\.api/PetApi\"\\);";
String reAddPetTest = "public void addPetTest\\(\\) throws Exception \\{\\s+"
+ "Pet pet = cache\\.getObject\\(\"/addPet/pet\", Pet\\.class\\);";
checkFile(generator, outputPath + "/src/test/java/org/openapitools/api/PetApiTest.java", true, reInitCache,
checkFile(Paths.get(outputPath + "/src/test/java/org/openapitools/api/PetApiTest.java"), true, reInitCache,
reAddPetTest);
checkFile(generator, outputPath + "/src/main/resources/test-data.json", true);
checkFile(Paths.get(outputPath + "/src/main/resources/test-data.json"), true);
checkFile(generator, outputPath + "/test-data-control.json", true);
checkFile(Paths.get(outputPath + "/test-data-control.json"), true);
}
@Test

View File

@ -10,11 +10,7 @@ import io.swagger.v3.oas.models.responses.ApiResponse;
import io.swagger.v3.oas.models.servers.Server;
import io.swagger.v3.parser.core.models.ParseOptions;
import org.openapitools.codegen.ClientOptInput;
import org.openapitools.codegen.CodegenConstants;
import org.openapitools.codegen.CodegenOperation;
import org.openapitools.codegen.MockDefaultGenerator;
import org.openapitools.codegen.TestUtils;
import org.openapitools.codegen.*;
import org.openapitools.codegen.config.CodegenConfigurator;
import org.openapitools.codegen.languages.AbstractJavaJAXRSServerCodegen;
import org.openapitools.codegen.languages.JavaClientCodegen;
@ -27,6 +23,8 @@ import org.testng.annotations.Test;
import java.io.File;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
@ -212,12 +210,12 @@ public class JavaJAXRSSpecServerCodegenTest extends JavaJaxrsBaseTest {
.setOutputDir(output.getAbsolutePath().replace("\\", "/"));
final ClientOptInput clientOptInput = configurator.toClientOptInput();
MockDefaultGenerator generator = new MockDefaultGenerator();
generator.opts(clientOptInput).generate();
DefaultGenerator generator = new DefaultGenerator();
List<File> files = generator.opts(clientOptInput).generate();
Map<String, String> generatedFiles = generator.getFiles();
validateJavaSourceFiles(generatedFiles);
TestUtils.ensureContainsFile(generatedFiles, output, "src/main/openapi/openapi.yaml");
validateJavaSourceFiles(files);
TestUtils.ensureContainsFile(files, output, "src/main/openapi/openapi.yaml");
output.deleteOnExit();
}
@ -237,12 +235,11 @@ public class JavaJAXRSSpecServerCodegenTest extends JavaJaxrsBaseTest {
.setOutputDir(output.getAbsolutePath().replace("\\", "/"));
final ClientOptInput clientOptInput = configurator.toClientOptInput();
MockDefaultGenerator generator = new MockDefaultGenerator();
generator.opts(clientOptInput).generate();
DefaultGenerator generator = new DefaultGenerator();
List<File> files = generator.opts(clientOptInput).generate();
Map<String, String> generatedFiles = generator.getFiles();
validateJavaSourceFiles(generatedFiles);
TestUtils.ensureDoesNotContainsFile(generatedFiles, output, "src/main/openapi/openapi.yaml");
validateJavaSourceFiles(files);
TestUtils.ensureDoesNotContainsFile(files, output, "src/main/openapi/openapi.yaml");
output.deleteOnExit();
}
@ -262,12 +259,12 @@ public class JavaJAXRSSpecServerCodegenTest extends JavaJaxrsBaseTest {
.setOutputDir(output.getAbsolutePath().replace("\\", "/"));
final ClientOptInput clientOptInput = configurator.toClientOptInput();
MockDefaultGenerator generator = new MockDefaultGenerator();
generator.opts(clientOptInput).generate();
DefaultGenerator generator = new DefaultGenerator();
List<File> files = generator.opts(clientOptInput).generate();
Map<String, String> generatedFiles = generator.getFiles();
validateJavaSourceFiles(generatedFiles);
TestUtils.ensureContainsFile(generatedFiles, output, "src/main/resources/META-INF/openapi.yaml");
validateJavaSourceFiles(files);
TestUtils.ensureContainsFile(files, output, "src/main/resources/META-INF/openapi.yaml");
output.deleteOnExit();
}
@ -287,12 +284,11 @@ public class JavaJAXRSSpecServerCodegenTest extends JavaJaxrsBaseTest {
.setOutputDir(output.getAbsolutePath().replace("\\", "/"));
final ClientOptInput clientOptInput = configurator.toClientOptInput();
MockDefaultGenerator generator = new MockDefaultGenerator();
generator.opts(clientOptInput).generate();
DefaultGenerator generator = new DefaultGenerator();
List<File> files = generator.opts(clientOptInput).generate();
Map<String, String> generatedFiles = generator.getFiles();
validateJavaSourceFiles(generatedFiles);
TestUtils.ensureContainsFile(generatedFiles, output, "openapi.yml");
validateJavaSourceFiles(files);
TestUtils.ensureContainsFile(files, output, "openapi.yml");
output.deleteOnExit();
}
@ -312,13 +308,13 @@ public class JavaJAXRSSpecServerCodegenTest extends JavaJaxrsBaseTest {
.setOutputDir(output.getAbsolutePath().replace("\\", "/"));
final ClientOptInput clientOptInput = configurator.toClientOptInput();
MockDefaultGenerator generator = new MockDefaultGenerator();
generator.opts(clientOptInput).generate();
DefaultGenerator generator = new DefaultGenerator(false);
List<File> files = generator.opts(clientOptInput).generate();
Map<String, String> generatedFiles = generator.getFiles();
validateJavaSourceFiles(generatedFiles);
TestUtils.ensureContainsFile(generatedFiles, output, "openapi.yml");
TestUtils.ensureContainsFile(generatedFiles, output, "src/gen/java/org/openapitools/api/DefaultApi.java");
validateJavaSourceFiles(files);
TestUtils.ensureContainsFile(files, output, "openapi.yml");
TestUtils.ensureContainsFile(files, output, "src/gen/java/org/openapitools/api/DefaultApi.java");
output.deleteOnExit();
}
@ -341,12 +337,12 @@ public class JavaJAXRSSpecServerCodegenTest extends JavaJaxrsBaseTest {
.openAPI(openAPI)
.config(codegen);
MockDefaultGenerator generator = new MockDefaultGenerator();
DefaultGenerator generator = new DefaultGenerator(false);
generator.opts(input).generate();
String path = outputPath + "/src/gen/java/org/openapitools/api/ExamplesApi.java";
Path path = Paths.get(outputPath + "/src/gen/java/org/openapitools/api/ExamplesApi.java");
assertFileContains(generator, path, "\nimport java.util.Set;\n");
assertFileContains(path, "\nimport java.util.Set;\n");
}
@Test
@ -366,11 +362,11 @@ public class JavaJAXRSSpecServerCodegenTest extends JavaJaxrsBaseTest {
.openAPI(openAPI)
.config(codegen);
MockDefaultGenerator generator = new MockDefaultGenerator();
DefaultGenerator generator = new DefaultGenerator();
generator.opts(input).generate();
String path = outputPath + "/src/gen/java/org/openapitools/api/ExamplesApi.java";
Path path = Paths.get(outputPath + "/src/gen/java/org/openapitools/api/ExamplesApi.java");
assertFileContains(generator, path, "\nimport java.util.Set;\n");
assertFileContains(path, "\nimport java.util.Set;\n");
}
}

View File

@ -5,6 +5,7 @@ import io.swagger.v3.oas.models.OpenAPI;
import io.swagger.v3.oas.models.media.StringSchema;
import io.swagger.v3.parser.core.models.ParseOptions;
import org.openapitools.codegen.ClientOptInput;
import org.openapitools.codegen.DefaultGenerator;
import org.openapitools.codegen.MockDefaultGenerator;
import org.openapitools.codegen.languages.AbstractJavaJAXRSServerCodegen;
import org.openapitools.codegen.languages.features.CXFServerFeatures;
@ -13,6 +14,7 @@ import org.testng.annotations.Test;
import java.io.File;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Paths;
import static org.openapitools.codegen.TestUtils.assertFileContains;
import static org.openapitools.codegen.TestUtils.assertFileNotContains;
@ -37,17 +39,16 @@ public abstract class JavaJaxrsBaseTest {
.openAPI(openAPI)
.config(codegen);
MockDefaultGenerator generator = new MockDefaultGenerator();
DefaultGenerator generator = new DefaultGenerator();
generator.opts(input).generate();
String jsonTypeInfo = "@JsonTypeInfo(use = JsonTypeInfo.Id.NAME, include = JsonTypeInfo.As.PROPERTY, property = \"className\", visible = true)";
String jsonSubType = "@JsonSubTypes({\n" +
" @JsonSubTypes.Type(value = Dog.class, name = \"Dog\"),\n" +
" @JsonSubTypes.Type(value = Cat.class, name = \"Cat\"),\n" +
" @JsonSubTypes.Type(value = BigDog.class, name = \"BigDog\"),\n" +
"})";
assertFileContains(generator, outputPath + "/src/gen/java/org/openapitools/model/Animal.java", jsonTypeInfo, jsonSubType);
assertFileContains(Paths.get(outputPath + "/src/gen/java/org/openapitools/model/Animal.java"), jsonTypeInfo, jsonSubType);
}
@ -68,7 +69,7 @@ public abstract class JavaJaxrsBaseTest {
.openAPI(openAPI)
.config(codegen);
MockDefaultGenerator generator = new MockDefaultGenerator();
DefaultGenerator generator = new DefaultGenerator();
generator.opts(input).generate();
@ -77,7 +78,7 @@ public abstract class JavaJaxrsBaseTest {
" @JsonSubTypes.Type(value = Dog.class, name = \"Dog\"),\n" +
" @JsonSubTypes.Type(value = Cat.class, name = \"Cat\"),\n" +
"})";
assertFileNotContains(generator, outputPath + "/src/gen/java/org/openapitools/model/Animal.java", jsonTypeInfo, jsonSubType);
assertFileNotContains(Paths.get(outputPath + "/src/gen/java/org/openapitools/model/Animal.java"), jsonTypeInfo, jsonSubType);
}
@ -97,10 +98,10 @@ public abstract class JavaJaxrsBaseTest {
.openAPI(openAPI)
.config(codegen);
MockDefaultGenerator generator = new MockDefaultGenerator();
DefaultGenerator generator = new DefaultGenerator();
generator.opts(input).generate();
assertFileNotContains(generator, outputPath + "/src/gen/java/org/openapitools/api/ExamplesApi.java", "DefaultValue");
assertFileNotContains(Paths.get(outputPath + "/src/gen/java/org/openapitools/api/ExamplesApi.java"), "DefaultValue");
}
@Test
@ -121,9 +122,9 @@ public abstract class JavaJaxrsBaseTest {
.openAPI(openAPI)
.config(codegen);
MockDefaultGenerator generator = new MockDefaultGenerator();
DefaultGenerator generator = new DefaultGenerator();
generator.opts(input).generate();
assertFileContains(generator, outputPath + "/src/gen/java/org/openapitools/api/ExamplesApi.java", "DefaultValue");
assertFileContains(Paths.get(outputPath + "/src/gen/java/org/openapitools/api/ExamplesApi.java"), "DefaultValue");
}
}

View File

@ -33,69 +33,309 @@ import org.testng.annotations.Test;
import java.io.File;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
import static java.util.stream.Collectors.groupingBy;
import static org.openapitools.codegen.TestUtils.assertFileContains;
import static org.openapitools.codegen.TestUtils.assertFileNotContains;
import static org.openapitools.codegen.languages.SpringCodegen.RESPONSE_WRAPPER;
import static org.testng.Assert.assertEquals;
import static org.testng.Assert.assertFalse;
import static org.testng.Assert.assertNotNull;
public class SpringCodegenTest {
@Test
public void testInitialConfigValues() throws Exception {
final SpringCodegen codegen = new SpringCodegen();
codegen.processOpts();
OpenAPI openAPI = new OpenAPI();
openAPI.addServersItem(new Server().url("https://api.abcde.xy:8082/v2"));
openAPI.setInfo(new Info());
codegen.preprocessOpenAPI(openAPI);
Assert.assertEquals(codegen.additionalProperties().get(CodegenConstants.HIDE_GENERATION_TIMESTAMP), Boolean.FALSE);
Assert.assertEquals(codegen.isHideGenerationTimestamp(), false);
Assert.assertEquals(codegen.modelPackage(), "org.openapitools.model");
Assert.assertEquals(codegen.additionalProperties().get(CodegenConstants.MODEL_PACKAGE), "org.openapitools.model");
Assert.assertEquals(codegen.apiPackage(), "org.openapitools.api");
Assert.assertEquals(codegen.additionalProperties().get(CodegenConstants.API_PACKAGE), "org.openapitools.api");
Assert.assertEquals(codegen.getInvokerPackage(), "org.openapitools.api");
Assert.assertEquals(codegen.additionalProperties().get(CodegenConstants.INVOKER_PACKAGE), "org.openapitools.api");
Assert.assertEquals(codegen.getBasePackage(), "org.openapitools");
Assert.assertEquals(codegen.additionalProperties().get(SpringCodegen.BASE_PACKAGE), "org.openapitools");
Assert.assertEquals(codegen.getConfigPackage(), "org.openapitools.configuration");
Assert.assertEquals(codegen.additionalProperties().get(SpringCodegen.CONFIG_PACKAGE), "org.openapitools.configuration");
Assert.assertEquals(codegen.additionalProperties().get(SpringCodegen.SERVER_PORT), "8082");
Assert.assertEquals(codegen.additionalProperties().get(SpringCodegen.UNHANDLED_EXCEPTION_HANDLING), false);
public void clientOptsUnicity() {
SpringCodegen codegen = new SpringCodegen();
codegen.cliOptions()
.stream()
.collect(groupingBy(CliOption::getOpt))
.forEach((k, v) -> assertEquals(v.size(), 1, k + " is described multiple times"));
}
@Test
public void testSettersForConfigValues() throws Exception {
public void doAnnotateDatesOnModelParameters() throws IOException {
File output = Files.createTempDirectory("test").toFile().getCanonicalFile();
output.deleteOnExit();
String outputPath = output.getAbsolutePath().replace('\\', '/');
OpenAPI openAPI = new OpenAPIParser()
.readLocation("src/test/resources/3_0/issue_5436.yml", null, new ParseOptions()).getOpenAPI();
SpringCodegen codegen = new SpringCodegen();
codegen.setOutputDir(output.getAbsolutePath());
codegen.additionalProperties().put(CXFServerFeatures.LOAD_TEST_DATA_FROM_FILE, "true");
ClientOptInput input = new ClientOptInput();
input.openAPI(openAPI);
input.config(codegen);
DefaultGenerator generator = new DefaultGenerator();
generator.setGeneratorPropertyDefault(CodegenConstants.MODELS, "true");
generator.setGeneratorPropertyDefault(CodegenConstants.MODEL_TESTS, "false");
generator.setGeneratorPropertyDefault(CodegenConstants.MODEL_DOCS, "false");
generator.setGeneratorPropertyDefault(CodegenConstants.APIS, "true");
generator.setGeneratorPropertyDefault(CodegenConstants.SUPPORTING_FILES, "false");
generator.opts(input).generate();
assertFileContains(Paths.get(outputPath + "/src/main/java/org/openapitools/api/ZebrasApi.java"),
"AnimalParams");
assertFileContains(Paths.get(outputPath + "/src/main/java/org/openapitools/model/AnimalParams.java"),
"@org.springframework.format.annotation.DateTimeFormat(iso = org.springframework.format.annotation.DateTimeFormat.ISO.DATE)",
"@org.springframework.format.annotation.DateTimeFormat(iso = org.springframework.format.annotation.DateTimeFormat.ISO.DATE_TIME)");
}
@Test
public void doGenerateCookieParams() throws IOException {
File output = Files.createTempDirectory("test").toFile().getCanonicalFile();
output.deleteOnExit();
String outputPath = output.getAbsolutePath().replace('\\', '/');
OpenAPI openAPI = new OpenAPIParser()
.readLocation("src/test/resources/3_0/issue_5386.yaml", null, new ParseOptions()).getOpenAPI();
SpringCodegen codegen = new SpringCodegen();
codegen.setOutputDir(output.getAbsolutePath());
codegen.additionalProperties().put(CXFServerFeatures.LOAD_TEST_DATA_FROM_FILE, "true");
ClientOptInput input = new ClientOptInput();
input.openAPI(openAPI);
input.config(codegen);
DefaultGenerator generator = new DefaultGenerator();
generator.setGeneratorPropertyDefault(CodegenConstants.MODELS, "false");
generator.setGeneratorPropertyDefault(CodegenConstants.MODEL_TESTS, "false");
generator.setGeneratorPropertyDefault(CodegenConstants.MODEL_DOCS, "false");
generator.setGeneratorPropertyDefault(CodegenConstants.APIS, "true");
generator.setGeneratorPropertyDefault(CodegenConstants.SUPPORTING_FILES, "false");
generator.opts(input).generate();
assertFileContains(Paths.get(outputPath + "/src/main/java/org/openapitools/api/ElephantsApi.java"), "@CookieValue");
assertFileContains(Paths.get(outputPath + "/src/main/java/org/openapitools/api/ZebrasApi.java"), "@CookieValue");
assertFileNotContains(Paths.get(outputPath + "/src/main/java/org/openapitools/api/BirdsApi.java"), "@CookieValue");
}
@Test
public void doGenerateRequestParamForSimpleParam() throws IOException {
File output = Files.createTempDirectory("test").toFile().getCanonicalFile();
output.deleteOnExit();
String outputPath = output.getAbsolutePath().replace('\\', '/');
OpenAPI openAPI = new OpenAPIParser()
.readLocation("src/test/resources/3_0/issue_3248.yaml", null, new ParseOptions()).getOpenAPI();
SpringCodegen codegen = new SpringCodegen();
codegen.setOutputDir(output.getAbsolutePath());
codegen.additionalProperties().put(CXFServerFeatures.LOAD_TEST_DATA_FROM_FILE, "true");
ClientOptInput input = new ClientOptInput();
input.openAPI(openAPI);
input.config(codegen);
DefaultGenerator generator = new DefaultGenerator();
generator.setGeneratorPropertyDefault(CodegenConstants.MODELS, "false");
generator.setGeneratorPropertyDefault(CodegenConstants.MODEL_TESTS, "false");
generator.setGeneratorPropertyDefault(CodegenConstants.MODEL_DOCS, "false");
generator.setGeneratorPropertyDefault(CodegenConstants.APIS, "true");
generator.setGeneratorPropertyDefault(CodegenConstants.SUPPORTING_FILES, "false");
generator.opts(input).generate();
assertFileContains(Paths.get(outputPath + "/src/main/java/org/openapitools/api/MonkeysApi.java"), "@RequestParam");
assertFileContains(Paths.get(outputPath + "/src/main/java/org/openapitools/api/ElephantsApi.java"), "@RequestParam");
assertFileContains(Paths.get(outputPath + "/src/main/java/org/openapitools/api/ZebrasApi.java"), "@RequestParam");
assertFileContains(Paths.get(outputPath + "/src/main/java/org/openapitools/api/BearsApi.java"), "@RequestParam");
assertFileContains(Paths.get(outputPath + "/src/main/java/org/openapitools/api/CamelsApi.java"), "@RequestParam");
assertFileContains(Paths.get(outputPath + "/src/main/java/org/openapitools/api/PandasApi.java"), "@RequestParam");
assertFileContains(Paths.get(outputPath + "/src/main/java/org/openapitools/api/CrocodilesApi.java"), "@RequestParam");
assertFileContains(Paths.get(outputPath + "/src/main/java/org/openapitools/api/PolarBearsApi.java"), "@RequestParam");
}
@Test
public void doNotGenerateRequestParamForObjectQueryParam() throws IOException {
File output = Files.createTempDirectory("test").toFile().getCanonicalFile();
output.deleteOnExit();
String outputPath = output.getAbsolutePath().replace('\\', '/');
OpenAPI openAPI = new OpenAPIParser()
.readLocation("src/test/resources/3_0/objectQueryParam.yaml", null, new ParseOptions()).getOpenAPI();
SpringCodegen codegen = new SpringCodegen();
codegen.setOutputDir(output.getAbsolutePath());
codegen.additionalProperties().put(CXFServerFeatures.LOAD_TEST_DATA_FROM_FILE, "true");
ClientOptInput input = new ClientOptInput();
input.setOpenAPI(openAPI);
input.setConfig(codegen);
DefaultGenerator generator = new DefaultGenerator();
generator.setGeneratorPropertyDefault(CodegenConstants.MODELS, "false");
generator.setGeneratorPropertyDefault(CodegenConstants.MODEL_TESTS, "false");
generator.setGeneratorPropertyDefault(CodegenConstants.MODEL_DOCS, "false");
generator.setGeneratorPropertyDefault(CodegenConstants.APIS, "true");
generator.setGeneratorPropertyDefault(CodegenConstants.SUPPORTING_FILES, "false");
generator.opts(input).generate();
assertFileNotContains(Paths.get(outputPath + "/src/main/java/org/openapitools/api/PonyApi.java"), "@RequestParam");
}
@Test
public void generateFormatForDateAndDateTimeQueryParam() throws IOException {
File output = Files.createTempDirectory("test").toFile().getCanonicalFile();
output.deleteOnExit();
String outputPath = output.getAbsolutePath().replace('\\', '/');
OpenAPI openAPI = new OpenAPIParser()
.readLocation("src/test/resources/3_0/issue_2053.yaml", null, new ParseOptions()).getOpenAPI();
SpringCodegen codegen = new SpringCodegen();
codegen.setOutputDir(output.getAbsolutePath());
codegen.additionalProperties().put(CXFServerFeatures.LOAD_TEST_DATA_FROM_FILE, "true");
ClientOptInput input = new ClientOptInput();
input.openAPI(openAPI);
input.config(codegen);
DefaultGenerator generator = new DefaultGenerator();
generator.setGeneratorPropertyDefault(CodegenConstants.MODELS, "false");
generator.setGeneratorPropertyDefault(CodegenConstants.MODEL_TESTS, "false");
generator.setGeneratorPropertyDefault(CodegenConstants.MODEL_DOCS, "false");
generator.setGeneratorPropertyDefault(CodegenConstants.APIS, "true");
generator.setGeneratorPropertyDefault(CodegenConstants.SUPPORTING_FILES, "false");
generator.opts(input).generate();
assertFileContains(
Paths.get(outputPath + "/src/main/java/org/openapitools/api/ElephantsApi.java"),
"@org.springframework.format.annotation.DateTimeFormat(iso = org.springframework.format.annotation.DateTimeFormat.ISO.DATE)"
);
assertFileContains(
Paths.get(outputPath + "/src/main/java/org/openapitools/api/ZebrasApi.java"),
"@org.springframework.format.annotation.DateTimeFormat(iso = org.springframework.format.annotation.DateTimeFormat.ISO.DATE_TIME)"
);
}
@Test
public void interfaceDefaultImplDisableWithReponseWrapper() {
final SpringCodegen codegen = new SpringCodegen();
codegen.setHideGenerationTimestamp(true);
codegen.setModelPackage("xx.yyyyyyyy.model");
codegen.setApiPackage("xx.yyyyyyyy.api");
codegen.setInvokerPackage("xx.yyyyyyyy.invoker");
codegen.setBasePackage("xx.yyyyyyyy.base");
codegen.setConfigPackage("xx.yyyyyyyy.config");
codegen.setUnhandledException(true);
codegen.additionalProperties().put(SpringCodegen.JAVA_8, true);
codegen.additionalProperties().put(RESPONSE_WRAPPER, "aWrapper");
codegen.processOpts();
Assert.assertEquals(codegen.additionalProperties().get(CodegenConstants.HIDE_GENERATION_TIMESTAMP), Boolean.TRUE);
Assert.assertEquals(codegen.isHideGenerationTimestamp(), true);
Assert.assertEquals(codegen.modelPackage(), "xx.yyyyyyyy.model");
Assert.assertEquals(codegen.additionalProperties().get(CodegenConstants.MODEL_PACKAGE), "xx.yyyyyyyy.model");
Assert.assertEquals(codegen.apiPackage(), "xx.yyyyyyyy.api");
Assert.assertEquals(codegen.additionalProperties().get(CodegenConstants.API_PACKAGE), "xx.yyyyyyyy.api");
Assert.assertEquals(codegen.getInvokerPackage(), "xx.yyyyyyyy.invoker");
Assert.assertEquals(codegen.additionalProperties().get(CodegenConstants.INVOKER_PACKAGE), "xx.yyyyyyyy.invoker");
Assert.assertEquals(codegen.getBasePackage(), "xx.yyyyyyyy.base");
Assert.assertEquals(codegen.additionalProperties().get(SpringCodegen.BASE_PACKAGE), "xx.yyyyyyyy.base");
Assert.assertEquals(codegen.getConfigPackage(), "xx.yyyyyyyy.config");
Assert.assertEquals(codegen.additionalProperties().get(SpringCodegen.CONFIG_PACKAGE), "xx.yyyyyyyy.config");
Assert.assertEquals(codegen.isUnhandledException(), true);
Assert.assertEquals(codegen.additionalProperties().get(SpringCodegen.UNHANDLED_EXCEPTION_HANDLING), true);
Assert.assertEquals(codegen.additionalProperties().get("jdk8"), false);
}
@Test(expectedExceptions = IllegalArgumentException.class)
public void reactiveRequiredSpringBoot() {
final SpringCodegen codegen = new SpringCodegen();
codegen.additionalProperties().put(SpringCodegen.REACTIVE, true);
codegen.additionalProperties().put(CodegenConstants.LIBRARY, "spring-cloud");
codegen.processOpts();
}
@Test
public void shouldGenerateRequestParamForRefParams_3248_Regression() throws IOException {
File output = Files.createTempDirectory("test").toFile().getCanonicalFile();
output.deleteOnExit();
String outputPath = output.getAbsolutePath().replace('\\', '/');
OpenAPI openAPI = new OpenAPIParser()
.readLocation("src/test/resources/3_0/3248-regression.yaml", null, new ParseOptions()).getOpenAPI();
SpringCodegen codegen = new SpringCodegen();
codegen.setOutputDir(output.getAbsolutePath());
codegen.additionalProperties().put(CXFServerFeatures.LOAD_TEST_DATA_FROM_FILE, "true");
ClientOptInput input = new ClientOptInput();
input.setOpenAPI(openAPI);
input.setConfig(codegen);
DefaultGenerator generator = new DefaultGenerator();
generator.setGeneratorPropertyDefault(CodegenConstants.MODELS, "false");
generator.setGeneratorPropertyDefault(CodegenConstants.MODEL_TESTS, "false");
generator.setGeneratorPropertyDefault(CodegenConstants.MODEL_DOCS, "false");
generator.setGeneratorPropertyDefault(CodegenConstants.APIS, "true");
generator.setGeneratorPropertyDefault(CodegenConstants.SUPPORTING_FILES, "false");
generator.opts(input).generate();
assertFileContains(Paths.get(outputPath + "/src/main/java/org/openapitools/api/ExampleApi.java"),
"@RequestParam(value = \"format\"",
"@RequestParam(value = \"query\"");
}
@Test
public void shouldGenerateRequestParamForRefParams_3248_RegressionDates() throws IOException {
File output = Files.createTempDirectory("test").toFile().getCanonicalFile();
output.deleteOnExit();
String outputPath = output.getAbsolutePath().replace('\\', '/');
OpenAPI openAPI = new OpenAPIParser()
.readLocation("src/test/resources/3_0/3248-regression-dates.yaml", null, new ParseOptions()).getOpenAPI();
SpringCodegen codegen = new SpringCodegen();
codegen.setOutputDir(output.getAbsolutePath());
codegen.additionalProperties().put(CXFServerFeatures.LOAD_TEST_DATA_FROM_FILE, "true");
ClientOptInput input = new ClientOptInput();
input.setOpenAPI(openAPI);
input.setConfig(codegen);
DefaultGenerator generator = new DefaultGenerator();
generator.setGeneratorPropertyDefault(CodegenConstants.MODELS, "false");
generator.setGeneratorPropertyDefault(CodegenConstants.MODEL_TESTS, "false");
generator.setGeneratorPropertyDefault(CodegenConstants.MODEL_DOCS, "false");
generator.setGeneratorPropertyDefault(CodegenConstants.APIS, "true");
generator.setGeneratorPropertyDefault(CodegenConstants.SUPPORTING_FILES, "false");
generator.opts(input).generate();
assertFileContains(Paths.get(outputPath + "/src/main/java/org/openapitools/api/ExampleApi.java"),
"@RequestParam(value = \"start\"");
}
@Test
public void springcloudWithAsyncAndJava8HasResponseWrapperCompletableFuture() {
final SpringCodegen codegen = new SpringCodegen();
codegen.additionalProperties().put(SpringCodegen.JAVA_8, true);
codegen.additionalProperties().put(SpringCodegen.ASYNC, true);
codegen.additionalProperties().put(CodegenConstants.LIBRARY, "spring-cloud");
codegen.processOpts();
Assert.assertEquals(codegen.additionalProperties().get("jdk8-default-interface"), false);
Assert.assertEquals(codegen.additionalProperties().get(RESPONSE_WRAPPER), "CompletableFuture");
}
@Test
public void springcloudWithAsyncHasResponseWrapperCallable() {
final SpringCodegen codegen = new SpringCodegen();
codegen.additionalProperties().put(SpringCodegen.JAVA_8, false);
codegen.additionalProperties().put(SpringCodegen.ASYNC, true);
codegen.additionalProperties().put(CodegenConstants.LIBRARY, "spring-cloud");
codegen.processOpts();
Assert.assertNull(codegen.additionalProperties().get("jdk8-default-interface"));
Assert.assertEquals(codegen.additionalProperties().get(RESPONSE_WRAPPER), "Callable");
}
@Test
public void springcloudWithJava8DisabeJdk8() {
final SpringCodegen codegen = new SpringCodegen();
codegen.additionalProperties().put(SpringCodegen.JAVA_8, true);
codegen.additionalProperties().put(CodegenConstants.LIBRARY, "spring-cloud");
codegen.processOpts();
Assert.assertEquals(codegen.additionalProperties().get("jdk8-default-interface"), false);
}
@Test
@ -132,360 +372,6 @@ public class SpringCodegenTest {
Assert.assertEquals(codegen.additionalProperties().get(SpringCodegen.SERVER_PORT), "8088");
}
@Test
public void interfaceDefaultImplDisableWithReponseWrapper() {
final SpringCodegen codegen = new SpringCodegen();
codegen.additionalProperties().put(SpringCodegen.JAVA_8, true);
codegen.additionalProperties().put(RESPONSE_WRAPPER, "aWrapper");
codegen.processOpts();
Assert.assertEquals(codegen.additionalProperties().get("jdk8"), false);
}
@Test
public void doNotGenerateRequestParamForObjectQueryParam() throws IOException {
File output = Files.createTempDirectory("test").toFile().getCanonicalFile();
output.deleteOnExit();
String outputPath = output.getAbsolutePath().replace('\\', '/');
OpenAPI openAPI = new OpenAPIParser()
.readLocation("src/test/resources/3_0/objectQueryParam.yaml", null, new ParseOptions()).getOpenAPI();
SpringCodegen codegen = new SpringCodegen();
codegen.setOutputDir(output.getAbsolutePath());
codegen.additionalProperties().put(CXFServerFeatures.LOAD_TEST_DATA_FROM_FILE, "true");
ClientOptInput input = new ClientOptInput();
input.setOpenAPI(openAPI);
input.setConfig(codegen);
MockDefaultGenerator generator = new MockDefaultGenerator();
generator.opts(input).generate();
checkFileNotContains(generator, outputPath + "/src/main/java/org/openapitools/api/PonyApi.java", "@RequestParam");
}
@Test
public void generateFormatForDateAndDateTimeQueryParam() throws IOException {
File output = Files.createTempDirectory("test").toFile().getCanonicalFile();
output.deleteOnExit();
String outputPath = output.getAbsolutePath().replace('\\', '/');
OpenAPI openAPI = new OpenAPIParser()
.readLocation("src/test/resources/3_0/issue_2053.yaml", null, new ParseOptions()).getOpenAPI();
SpringCodegen codegen = new SpringCodegen();
codegen.setOutputDir(output.getAbsolutePath());
codegen.additionalProperties().put(CXFServerFeatures.LOAD_TEST_DATA_FROM_FILE, "true");
ClientOptInput input = new ClientOptInput();
input.openAPI(openAPI);
input.config(codegen);
MockDefaultGenerator generator = new MockDefaultGenerator();
generator.opts(input).generate();
checkFileContains(
generator,
outputPath + "/src/main/java/org/openapitools/api/ElephantsApi.java",
"@org.springframework.format.annotation.DateTimeFormat(iso = org.springframework.format.annotation.DateTimeFormat.ISO.DATE)"
);
checkFileContains(
generator,
outputPath + "/src/main/java/org/openapitools/api/ZebrasApi.java",
"@org.springframework.format.annotation.DateTimeFormat(iso = org.springframework.format.annotation.DateTimeFormat.ISO.DATE_TIME)"
);
}
@Test
public void shouldGenerateRequestParamForRefParams_3248_Regression() throws IOException {
File output = Files.createTempDirectory("test").toFile().getCanonicalFile();
output.deleteOnExit();
String outputPath = output.getAbsolutePath().replace('\\', '/');
OpenAPI openAPI = new OpenAPIParser()
.readLocation("src/test/resources/3_0/3248-regression.yaml", null, new ParseOptions()).getOpenAPI();
SpringCodegen codegen = new SpringCodegen();
codegen.setOutputDir(output.getAbsolutePath());
codegen.additionalProperties().put(CXFServerFeatures.LOAD_TEST_DATA_FROM_FILE, "true");
ClientOptInput input = new ClientOptInput();
input.setOpenAPI(openAPI);
input.setConfig(codegen);
MockDefaultGenerator generator = new MockDefaultGenerator();
generator.opts(input).generate();
checkFileContains(generator, outputPath + "/src/main/java/org/openapitools/api/ExampleApi.java",
"@RequestParam(value = \"format\"",
"@RequestParam(value = \"query\"");
}
@Test
public void shouldGenerateRequestParamForRefParams_3248_RegressionDates() throws IOException {
File output = Files.createTempDirectory("test").toFile().getCanonicalFile();
output.deleteOnExit();
String outputPath = output.getAbsolutePath().replace('\\', '/');
OpenAPI openAPI = new OpenAPIParser()
.readLocation("src/test/resources/3_0/3248-regression-dates.yaml", null, new ParseOptions()).getOpenAPI();
SpringCodegen codegen = new SpringCodegen();
codegen.setOutputDir(output.getAbsolutePath());
codegen.additionalProperties().put(CXFServerFeatures.LOAD_TEST_DATA_FROM_FILE, "true");
ClientOptInput input = new ClientOptInput();
input.setOpenAPI(openAPI);
input.setConfig(codegen);
MockDefaultGenerator generator = new MockDefaultGenerator();
generator.opts(input).generate();
checkFileContains(generator, outputPath + "/src/main/java/org/openapitools/api/ExampleApi.java",
"@RequestParam(value = \"start\"");
}
// Helper function, intended to reduce boilerplate
private Map<String, String> generateFiles(SpringCodegen codegen, String filePath) throws IOException {
final File output = Files.createTempDirectory("test").toFile().getCanonicalFile();
output.deleteOnExit();
final String outputPath = output.getAbsolutePath().replace('\\', '/');
codegen.setOutputDir(output.getAbsolutePath());
codegen.additionalProperties().put(CXFServerFeatures.LOAD_TEST_DATA_FROM_FILE, "true");
final ClientOptInput input = new ClientOptInput();
final OpenAPI openAPI = new OpenAPIParser().readLocation(filePath, null, new ParseOptions()).getOpenAPI();
input.openAPI(openAPI);
input.config(codegen);
final MockDefaultGenerator generator = new MockDefaultGenerator();
generator.opts(input).generate();
return generator.getFiles().entrySet().stream().collect(Collectors.toMap(e -> e.getKey().replace(outputPath, ""), Map.Entry::getValue));
}
@Test
public void testMultipartBoot() throws IOException {
final SpringCodegen codegen = new SpringCodegen();
codegen.setLibrary("spring-boot");
codegen.setDelegatePattern(true);
final Map<String, String> files = generateFiles(codegen, "src/test/resources/3_0/form-multipart-binary-array.yaml");
// Check that the delegate handles the array
final String multipartArrayApiDelegate = files.get("/src/main/java/org/openapitools/api/MultipartArrayApiDelegate.java");
Assert.assertTrue(multipartArrayApiDelegate.contains("List<MultipartFile> files"));
// Check that the api handles the array
final String multipartArrayApi = files.get("/src/main/java/org/openapitools/api/MultipartArrayApi.java");
Assert.assertTrue(multipartArrayApi.contains("List<MultipartFile> files"));
Assert.assertTrue(multipartArrayApi.contains("@ApiParam(value = \"Many files\")"));
Assert.assertTrue(multipartArrayApi.contains("@RequestPart(value = \"files\", required = false)"));
// Check that the delegate handles the single file
final String multipartSingleApiDelegate = files.get("/src/main/java/org/openapitools/api/MultipartSingleApiDelegate.java");
Assert.assertTrue(multipartSingleApiDelegate.contains("MultipartFile file"));
// Check that the api handles the single file
final String multipartSingleApi = files.get("/src/main/java/org/openapitools/api/MultipartSingleApi.java");
Assert.assertTrue(multipartSingleApi.contains("MultipartFile file"));
Assert.assertTrue(multipartSingleApi.contains("@ApiParam(value = \"One file\")"));
Assert.assertTrue(multipartSingleApi.contains("@RequestPart(value = \"file\", required = false)"));
// Check that api validates mixed multipart request
final String multipartMixedApi = files.get("/src/main/java/org/openapitools/api/MultipartMixedApi.java");
Assert.assertTrue(multipartMixedApi.contains("MultipartFile file"));
Assert.assertTrue(multipartMixedApi.contains("@RequestPart(value = \"file\", required = true)"));
Assert.assertTrue(multipartMixedApi.contains("@Valid @RequestPart(value = \"marker\", required = false)"));
}
@Test
public void testMultipartCloud() throws IOException {
final SpringCodegen codegen = new SpringCodegen();
codegen.setLibrary("spring-cloud");
codegen.setDelegatePattern(true);
final Map<String, String> files = generateFiles(codegen, "src/test/resources/3_0/form-multipart-binary-array.yaml");
// Check that the delegate handles the array and the file
final String multipartApiDelegate = files.get("/src/main/java/org/openapitools/api/MultipartApiDelegate.java");
Assert.assertTrue(multipartApiDelegate.contains("List<MultipartFile> files"));
Assert.assertTrue(multipartApiDelegate.contains("MultipartFile file"));
// Check that the api handles the array and the file
final String multipartApi = files.get("/src/main/java/org/openapitools/api/MultipartApi.java");
Assert.assertTrue(multipartApi.contains("List<MultipartFile> files"));
Assert.assertTrue(multipartApi.contains("MultipartFile file"));
}
@Test
public void doGenerateRequestParamForSimpleParam() throws IOException {
File output = Files.createTempDirectory("test").toFile().getCanonicalFile();
output.deleteOnExit();
String outputPath = output.getAbsolutePath().replace('\\', '/');
OpenAPI openAPI = new OpenAPIParser()
.readLocation("src/test/resources/3_0/issue_3248.yaml", null, new ParseOptions()).getOpenAPI();
SpringCodegen codegen = new SpringCodegen();
codegen.setOutputDir(output.getAbsolutePath());
codegen.additionalProperties().put(CXFServerFeatures.LOAD_TEST_DATA_FROM_FILE, "true");
ClientOptInput input = new ClientOptInput();
input.openAPI(openAPI);
input.config(codegen);
MockDefaultGenerator generator = new MockDefaultGenerator();
generator.opts(input).generate();
checkFileContains(generator, outputPath + "/src/main/java/org/openapitools/api/MonkeysApi.java", "@RequestParam");
checkFileContains(generator, outputPath + "/src/main/java/org/openapitools/api/ElephantsApi.java", "@RequestParam");
checkFileContains(generator, outputPath + "/src/main/java/org/openapitools/api/ZebrasApi.java", "@RequestParam");
checkFileContains(generator, outputPath + "/src/main/java/org/openapitools/api/BearsApi.java", "@RequestParam");
checkFileContains(generator, outputPath + "/src/main/java/org/openapitools/api/CamelsApi.java", "@RequestParam");
checkFileContains(generator, outputPath + "/src/main/java/org/openapitools/api/PandasApi.java", "@RequestParam");
checkFileContains(generator, outputPath + "/src/main/java/org/openapitools/api/CrocodilesApi.java", "@RequestParam");
checkFileContains(generator, outputPath + "/src/main/java/org/openapitools/api/PolarBearsApi.java", "@RequestParam");
}
private void checkFileNotContains(MockDefaultGenerator generator, String path, String... lines) {
String file = generator.getFiles().get(path);
assertNotNull(file);
for (String line : lines)
assertFalse(file.contains(line));
}
private void checkFileContains(MockDefaultGenerator generator, String path, String... lines) {
String file = generator.getFiles().get(path);
assertNotNull(file);
int expectedCount = lines.length;
int actualCount = 0;
for (String line : lines) {
if (file.contains(line)) {
actualCount++;
}
}
assertEquals(actualCount, expectedCount, "File is missing " + (expectedCount - actualCount) + " expected lines.");
}
@Test
public void clientOptsUnicity() {
SpringCodegen codegen = new SpringCodegen();
codegen.cliOptions()
.stream()
.collect(groupingBy(CliOption::getOpt))
.forEach((k,v) -> assertEquals(v.size(), 1, k + " is described multiple times"));
}
@Test
public void springcloudWithJava8DisabeJdk8() {
final SpringCodegen codegen = new SpringCodegen();
codegen.additionalProperties().put(SpringCodegen.JAVA_8, true);
codegen.additionalProperties().put(CodegenConstants.LIBRARY, "spring-cloud");
codegen.processOpts();
Assert.assertEquals(codegen.additionalProperties().get("jdk8-default-interface"), false);
}
@Test
public void springcloudWithAsyncHasResponseWrapperCallable() {
final SpringCodegen codegen = new SpringCodegen();
codegen.additionalProperties().put(SpringCodegen.JAVA_8, false);
codegen.additionalProperties().put(SpringCodegen.ASYNC, true);
codegen.additionalProperties().put(CodegenConstants.LIBRARY, "spring-cloud");
codegen.processOpts();
Assert.assertNull(codegen.additionalProperties().get("jdk8-default-interface"));
Assert.assertEquals(codegen.additionalProperties().get(RESPONSE_WRAPPER), "Callable");
}
@Test
public void springcloudWithAsyncAndJava8HasResponseWrapperCompletableFuture() {
final SpringCodegen codegen = new SpringCodegen();
codegen.additionalProperties().put(SpringCodegen.JAVA_8, true);
codegen.additionalProperties().put(SpringCodegen.ASYNC, true);
codegen.additionalProperties().put(CodegenConstants.LIBRARY, "spring-cloud");
codegen.processOpts();
Assert.assertEquals(codegen.additionalProperties().get("jdk8-default-interface"), false);
Assert.assertEquals(codegen.additionalProperties().get(RESPONSE_WRAPPER), "CompletableFuture");
}
@Test(expectedExceptions = IllegalArgumentException.class)
public void reactiveRequiredSpringBoot() {
final SpringCodegen codegen = new SpringCodegen();
codegen.additionalProperties().put(SpringCodegen.REACTIVE, true);
codegen.additionalProperties().put(CodegenConstants.LIBRARY, "spring-cloud");
codegen.processOpts();
}
@Test
public void testDoGenerateRequestBodyRequiredAttribute_3134_Regression() throws Exception {
File output = Files.createTempDirectory("test").toFile().getCanonicalFile();
output.deleteOnExit();
String outputPath = output.getAbsolutePath().replace('\\', '/');
OpenAPI openAPI = new OpenAPIParser()
.readLocation("src/test/resources/3_0/3134-regression.yaml", null, new ParseOptions()).getOpenAPI();
SpringCodegen codegen = new SpringCodegen();
codegen.setOutputDir(output.getAbsolutePath());
codegen.additionalProperties().put(CXFServerFeatures.LOAD_TEST_DATA_FROM_FILE, "true");
ClientOptInput input = new ClientOptInput();
input.setOpenAPI(openAPI);
input.setConfig(codegen);
MockDefaultGenerator generator = new MockDefaultGenerator();
generator.opts(input).generate();
checkFileContains(generator, outputPath + "/src/main/java/org/openapitools/api/ExampleApi.java",
"@RequestBody(required = false");
}
@Test
public void useBeanValidationTruePerformBeanValidationTrueJava8FalseForFormatEmail() throws IOException {
beanValidationForFormatEmail(true, true, false, "@org.hibernate.validator.constraints.Email", "@javax.validation.constraints.Email");
}
@Test
public void useBeanValidationTruePerformBeanValidationFalseJava8TrueForFormatEmail() throws IOException {
beanValidationForFormatEmail(true, false, true, "@javax.validation.constraints.Email", "@org.hibernate.validator.constraints.Email");
}
@Test
public void useBeanValidationTruePerformBeanValidationTrueJava8TrueForFormatEmail() throws IOException {
beanValidationForFormatEmail(true, true, true, "@javax.validation.constraints.Email", "@org.hibernate.validator.constraints.Email");
}
private void beanValidationForFormatEmail(boolean useBeanValidation, boolean performBeanValidation, boolean java8, String contains, String notContains) throws IOException {
File output = Files.createTempDirectory("test").toFile().getCanonicalFile();
output.deleteOnExit();
String outputPath = output.getAbsolutePath().replace('\\', '/');
OpenAPI openAPI = new OpenAPIParser()
.readLocation("src/test/resources/3_0/issue_4876_format_email.yaml", null, new ParseOptions()).getOpenAPI();
SpringCodegen codegen = new SpringCodegen();
codegen.setOutputDir(output.getAbsolutePath());
codegen.setUseBeanValidation(useBeanValidation);
codegen.setPerformBeanValidation(performBeanValidation);
codegen.setJava8(java8);
ClientOptInput input = new ClientOptInput();
input.openAPI(openAPI);
input.config(codegen);
MockDefaultGenerator generator = new MockDefaultGenerator();
generator.opts(input).generate();
checkFileContains(generator, outputPath + "/src/main/java/org/openapitools/model/PersonWithEmail.java", contains);
checkFileNotContains(generator, outputPath + "/src/main/java/org/openapitools/model/PersonWithEmail.java", notContains);
}
@Test
public void testDefaultValuesFixed() {
// we had an issue where int64, float, and double values were having single character string suffixes
@ -527,54 +413,210 @@ public class SpringCodegenTest {
}
@Test
public void doGenerateCookieParams() throws IOException {
public void testDoGenerateRequestBodyRequiredAttribute_3134_Regression() throws Exception {
File output = Files.createTempDirectory("test").toFile().getCanonicalFile();
output.deleteOnExit();
String outputPath = output.getAbsolutePath().replace('\\', '/');
OpenAPI openAPI = new OpenAPIParser()
.readLocation("src/test/resources/3_0/issue_5386.yaml", null, new ParseOptions()).getOpenAPI();
.readLocation("src/test/resources/3_0/3134-regression.yaml", null, new ParseOptions()).getOpenAPI();
SpringCodegen codegen = new SpringCodegen();
codegen.setOutputDir(output.getAbsolutePath());
codegen.additionalProperties().put(CXFServerFeatures.LOAD_TEST_DATA_FROM_FILE, "true");
ClientOptInput input = new ClientOptInput();
input.openAPI(openAPI);
input.config(codegen);
input.setOpenAPI(openAPI);
input.setConfig(codegen);
DefaultGenerator generator = new DefaultGenerator();
generator.setGeneratorPropertyDefault(CodegenConstants.MODELS, "false");
generator.setGeneratorPropertyDefault(CodegenConstants.MODEL_TESTS, "false");
generator.setGeneratorPropertyDefault(CodegenConstants.MODEL_DOCS, "false");
generator.setGeneratorPropertyDefault(CodegenConstants.APIS, "true");
generator.setGeneratorPropertyDefault(CodegenConstants.SUPPORTING_FILES, "false");
MockDefaultGenerator generator = new MockDefaultGenerator();
generator.opts(input).generate();
checkFileContains(generator, outputPath + "/src/main/java/org/openapitools/api/ElephantsApi.java", "@CookieValue");
checkFileContains(generator, outputPath + "/src/main/java/org/openapitools/api/ZebrasApi.java", "@CookieValue");
checkFileNotContains(generator, outputPath + "/src/main/java/org/openapitools/api/BirdsApi.java", "@CookieValue");
assertFileContains(Paths.get(outputPath + "/src/main/java/org/openapitools/api/ExampleApi.java"),
"@RequestBody(required = false");
}
@Test
public void doAnnotateDatesOnModelParameters() throws IOException {
public void testInitialConfigValues() throws Exception {
final SpringCodegen codegen = new SpringCodegen();
codegen.processOpts();
OpenAPI openAPI = new OpenAPI();
openAPI.addServersItem(new Server().url("https://api.abcde.xy:8082/v2"));
openAPI.setInfo(new Info());
codegen.preprocessOpenAPI(openAPI);
Assert.assertEquals(codegen.additionalProperties().get(CodegenConstants.HIDE_GENERATION_TIMESTAMP), Boolean.FALSE);
Assert.assertEquals(codegen.isHideGenerationTimestamp(), false);
Assert.assertEquals(codegen.modelPackage(), "org.openapitools.model");
Assert.assertEquals(codegen.additionalProperties().get(CodegenConstants.MODEL_PACKAGE), "org.openapitools.model");
Assert.assertEquals(codegen.apiPackage(), "org.openapitools.api");
Assert.assertEquals(codegen.additionalProperties().get(CodegenConstants.API_PACKAGE), "org.openapitools.api");
Assert.assertEquals(codegen.getInvokerPackage(), "org.openapitools.api");
Assert.assertEquals(codegen.additionalProperties().get(CodegenConstants.INVOKER_PACKAGE), "org.openapitools.api");
Assert.assertEquals(codegen.getBasePackage(), "org.openapitools");
Assert.assertEquals(codegen.additionalProperties().get(SpringCodegen.BASE_PACKAGE), "org.openapitools");
Assert.assertEquals(codegen.getConfigPackage(), "org.openapitools.configuration");
Assert.assertEquals(codegen.additionalProperties().get(SpringCodegen.CONFIG_PACKAGE), "org.openapitools.configuration");
Assert.assertEquals(codegen.additionalProperties().get(SpringCodegen.SERVER_PORT), "8082");
Assert.assertEquals(codegen.additionalProperties().get(SpringCodegen.UNHANDLED_EXCEPTION_HANDLING), false);
}
@Test
public void testMultipartBoot() throws IOException {
final SpringCodegen codegen = new SpringCodegen();
codegen.setLibrary("spring-boot");
codegen.setDelegatePattern(true);
final Map<String, File> files = generateFiles(codegen, "src/test/resources/3_0/form-multipart-binary-array.yaml");
// Check that the delegate handles the array
final File multipartArrayApiDelegate = files.get("MultipartArrayApiDelegate.java");
assertFileContains(multipartArrayApiDelegate.toPath(), "List<MultipartFile> files");
// Check that the api handles the array
final File multipartArrayApi = files.get("MultipartArrayApi.java");
assertFileContains(multipartArrayApi.toPath(), "List<MultipartFile> files",
"@ApiParam(value = \"Many files\")",
"@RequestPart(value = \"files\", required = false)");
// Check that the delegate handles the single file
final File multipartSingleApiDelegate = files.get("MultipartSingleApiDelegate.java");
assertFileContains(multipartSingleApiDelegate.toPath(), "MultipartFile file");
// Check that the api handles the single file
final File multipartSingleApi = files.get("MultipartSingleApi.java");
assertFileContains(multipartSingleApi.toPath(), "MultipartFile file",
"@ApiParam(value = \"One file\")",
"@RequestPart(value = \"file\", required = false)");
// Check that api validates mixed multipart request
final File multipartMixedApi = files.get("MultipartMixedApi.java");
assertFileContains(multipartMixedApi.toPath(), "MultipartFile file",
"@RequestPart(value = \"file\", required = true)",
"@Valid @RequestPart(value = \"marker\", required = false)");
}
// Helper function, intended to reduce boilerplate
private Map<String, File> generateFiles(SpringCodegen codegen, String filePath) throws IOException {
final File output = Files.createTempDirectory("test").toFile().getCanonicalFile();
output.deleteOnExit();
final String outputPath = output.getAbsolutePath().replace('\\', '/');
codegen.setOutputDir(output.getAbsolutePath());
codegen.additionalProperties().put(CXFServerFeatures.LOAD_TEST_DATA_FROM_FILE, "true");
final ClientOptInput input = new ClientOptInput();
final OpenAPI openAPI = new OpenAPIParser().readLocation(filePath, null, new ParseOptions()).getOpenAPI();
input.openAPI(openAPI);
input.config(codegen);
final DefaultGenerator generator = new DefaultGenerator();
List<File> files = generator.opts(input).generate();
return files.stream().collect(Collectors.toMap(e -> e.getName().replace(outputPath, ""), i -> i));
}
@Test
public void testMultipartCloud() throws IOException {
final SpringCodegen codegen = new SpringCodegen();
codegen.setLibrary("spring-cloud");
codegen.setDelegatePattern(true);
final Map<String, File> files = generateFiles(codegen, "src/test/resources/3_0/form-multipart-binary-array.yaml");
// Check that the delegate handles the array and the file
final File multipartApiDelegate = files.get("MultipartApiDelegate.java");
assertFileContains(multipartApiDelegate.toPath(),
"List<MultipartFile> files",
"MultipartFile file");
// Check that the api handles the array and the file
final File multipartApi = files.get("MultipartApi.java");
assertFileContains(multipartApi.toPath(),
"List<MultipartFile> files",
"MultipartFile file");
}
@Test
public void testSettersForConfigValues() throws Exception {
final SpringCodegen codegen = new SpringCodegen();
codegen.setHideGenerationTimestamp(true);
codegen.setModelPackage("xx.yyyyyyyy.model");
codegen.setApiPackage("xx.yyyyyyyy.api");
codegen.setInvokerPackage("xx.yyyyyyyy.invoker");
codegen.setBasePackage("xx.yyyyyyyy.base");
codegen.setConfigPackage("xx.yyyyyyyy.config");
codegen.setUnhandledException(true);
codegen.processOpts();
Assert.assertEquals(codegen.additionalProperties().get(CodegenConstants.HIDE_GENERATION_TIMESTAMP), Boolean.TRUE);
Assert.assertEquals(codegen.isHideGenerationTimestamp(), true);
Assert.assertEquals(codegen.modelPackage(), "xx.yyyyyyyy.model");
Assert.assertEquals(codegen.additionalProperties().get(CodegenConstants.MODEL_PACKAGE), "xx.yyyyyyyy.model");
Assert.assertEquals(codegen.apiPackage(), "xx.yyyyyyyy.api");
Assert.assertEquals(codegen.additionalProperties().get(CodegenConstants.API_PACKAGE), "xx.yyyyyyyy.api");
Assert.assertEquals(codegen.getInvokerPackage(), "xx.yyyyyyyy.invoker");
Assert.assertEquals(codegen.additionalProperties().get(CodegenConstants.INVOKER_PACKAGE), "xx.yyyyyyyy.invoker");
Assert.assertEquals(codegen.getBasePackage(), "xx.yyyyyyyy.base");
Assert.assertEquals(codegen.additionalProperties().get(SpringCodegen.BASE_PACKAGE), "xx.yyyyyyyy.base");
Assert.assertEquals(codegen.getConfigPackage(), "xx.yyyyyyyy.config");
Assert.assertEquals(codegen.additionalProperties().get(SpringCodegen.CONFIG_PACKAGE), "xx.yyyyyyyy.config");
Assert.assertEquals(codegen.isUnhandledException(), true);
Assert.assertEquals(codegen.additionalProperties().get(SpringCodegen.UNHANDLED_EXCEPTION_HANDLING), true);
}
@Test
public void useBeanValidationTruePerformBeanValidationFalseJava8TrueForFormatEmail() throws IOException {
beanValidationForFormatEmail(true, false, true, "@javax.validation.constraints.Email", "@org.hibernate.validator.constraints.Email");
}
@Test
public void useBeanValidationTruePerformBeanValidationTrueJava8FalseForFormatEmail() throws IOException {
beanValidationForFormatEmail(true, true, false, "@org.hibernate.validator.constraints.Email", "@javax.validation.constraints.Email");
}
private void beanValidationForFormatEmail(boolean useBeanValidation, boolean performBeanValidation, boolean java8, String contains, String notContains) throws IOException {
File output = Files.createTempDirectory("test").toFile().getCanonicalFile();
output.deleteOnExit();
String outputPath = output.getAbsolutePath().replace('\\', '/');
OpenAPI openAPI = new OpenAPIParser()
.readLocation("src/test/resources/3_0/issue_5436.yml", null, new ParseOptions()).getOpenAPI();
.readLocation("src/test/resources/3_0/issue_4876_format_email.yaml", null, new ParseOptions()).getOpenAPI();
SpringCodegen codegen = new SpringCodegen();
codegen.setOutputDir(output.getAbsolutePath());
codegen.additionalProperties().put(CXFServerFeatures.LOAD_TEST_DATA_FROM_FILE, "true");
codegen.setUseBeanValidation(useBeanValidation);
codegen.setPerformBeanValidation(performBeanValidation);
codegen.setJava8(java8);
ClientOptInput input = new ClientOptInput();
input.openAPI(openAPI);
input.config(codegen);
MockDefaultGenerator generator = new MockDefaultGenerator();
generator.opts(input).generate();
DefaultGenerator generator = new DefaultGenerator();
checkFileContains(generator, outputPath + "/src/main/java/org/openapitools/api/ZebrasApi.java",
"AnimalParams");
checkFileContains(generator, outputPath + "/src/main/java/org/openapitools/model/AnimalParams.java",
"@org.springframework.format.annotation.DateTimeFormat(iso = org.springframework.format.annotation.DateTimeFormat.ISO.DATE)",
"@org.springframework.format.annotation.DateTimeFormat(iso = org.springframework.format.annotation.DateTimeFormat.ISO.DATE_TIME)");
generator.setGeneratorPropertyDefault(CodegenConstants.MODELS, "true");
generator.setGeneratorPropertyDefault(CodegenConstants.MODEL_TESTS, "false");
generator.setGeneratorPropertyDefault(CodegenConstants.MODEL_DOCS, "false");
generator.setGeneratorPropertyDefault(CodegenConstants.APIS, "false");
generator.setGeneratorPropertyDefault(CodegenConstants.SUPPORTING_FILES, "false");
List<File> files = generator.opts(input).generate();
assertFileContains(Paths.get(outputPath + "/src/main/java/org/openapitools/model/PersonWithEmail.java"), contains);
assertFileNotContains(Paths.get(outputPath + "/src/main/java/org/openapitools/model/PersonWithEmail.java"), notContains);
}
@Test
public void useBeanValidationTruePerformBeanValidationTrueJava8TrueForFormatEmail() throws IOException {
beanValidationForFormatEmail(true, true, true, "@javax.validation.constraints.Email", "@org.hibernate.validator.constraints.Email");
}
}

View File

@ -5,7 +5,7 @@ import io.swagger.v3.oas.models.OpenAPI;
import io.swagger.v3.parser.core.models.ParseOptions;
import org.openapitools.codegen.ClientOptInput;
import org.openapitools.codegen.CodegenConstants;
import org.openapitools.codegen.MockDefaultGenerator;
import org.openapitools.codegen.DefaultGenerator;
import org.openapitools.codegen.languages.AbstractKotlinCodegen;
import org.openapitools.codegen.languages.KotlinClientCodegen;
import org.openapitools.codegen.languages.KotlinServerCodegen;
@ -17,6 +17,7 @@ import org.testng.annotations.Test;
import java.io.File;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Paths;
import static org.openapitools.codegen.TestUtils.assertFileContains;
@ -64,9 +65,16 @@ public class KotlinModelCodegenTest {
.openAPI(openAPI)
.config(codegen);
MockDefaultGenerator generator = new MockDefaultGenerator();
DefaultGenerator generator = new DefaultGenerator();
generator.setGeneratorPropertyDefault(CodegenConstants.MODELS, "true");
generator.setGeneratorPropertyDefault(CodegenConstants.MODEL_TESTS, "false");
generator.setGeneratorPropertyDefault(CodegenConstants.MODEL_DOCS, "false");
generator.setGeneratorPropertyDefault(CodegenConstants.APIS, "false");
generator.setGeneratorPropertyDefault(CodegenConstants.SUPPORTING_FILES, "true");
generator.opts(input).generate();
assertFileContains(generator, outputPath + "/src/main/kotlin/models/Animal.kt", props);
assertFileContains(Paths.get(outputPath + "/src/main/kotlin/models/Animal.kt"), props);
}
}

View File

@ -24,6 +24,7 @@ import io.swagger.v3.oas.models.media.*;
import io.swagger.v3.parser.util.SchemaTypeUtil;
import org.openapitools.codegen.*;
import org.openapitools.codegen.config.CodegenConfigurator;
import org.openapitools.codegen.config.GlobalSettings;
import org.openapitools.codegen.languages.ScalaAkkaClientCodegen;
import org.testng.Assert;
import org.testng.annotations.Test;
@ -32,8 +33,10 @@ import java.io.File;
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
@SuppressWarnings({"UnstableApiUsage", "OptionalGetWithoutIsPresent"})
public class ScalaAkkaClientCodegenTest {
private ScalaAkkaClientCodegen scalaAkkaClientCodegen;
@ -353,15 +356,28 @@ public class ScalaAkkaClientCodegenTest {
.setOutputDir(output.getAbsolutePath().replace("\\", "/"));
final ClientOptInput clientOptInput = configurator.toClientOptInput();
MockDefaultGenerator generator = new MockDefaultGenerator();
generator.opts(clientOptInput).generate();
DefaultGenerator generator = new DefaultGenerator();
Map<String, String> generatedFiles = generator.getFiles();
Assert.assertEquals(generatedFiles.size(), 14);
generator.setGenerateMetadata(false);
final String someObjFilename = new File(output, "src/main/scala/hello/world/model/SomeObj.scala").getAbsolutePath().replace("\\", "/");
generator.setGeneratorPropertyDefault(CodegenConstants.MODELS, "true");
generator.setGeneratorPropertyDefault(CodegenConstants.MODEL_TESTS, "false");
generator.setGeneratorPropertyDefault(CodegenConstants.MODEL_DOCS, "false");
generator.setGeneratorPropertyDefault(CodegenConstants.APIS, "false");
generator.setGeneratorPropertyDefault(CodegenConstants.SUPPORTING_FILES, "false");
List<File> files = generator.opts(clientOptInput).generate();
Assert.assertEquals(files.size(), 1);
TestUtils.ensureContainsFile(files, output, "src/main/scala/hello/world/model/SomeObj.scala");
File someObj = files.stream().filter(f -> f.getName().equals("SomeObj.scala"))
.findFirst().get();
byte[] fileContents = Files.readAllBytes(someObj.toPath());
Assert.assertEquals(
generatedFiles.get(someObjFilename),
new String(fileContents, StandardCharsets.UTF_8),
Resources.toString(Resources.getResource("codegen/scala/SomeObj.scala.txt"), StandardCharsets.UTF_8));
}
@ -383,15 +399,28 @@ public class ScalaAkkaClientCodegenTest {
.setOutputDir(output.getAbsolutePath().replace("\\", "/"));
final ClientOptInput clientOptInput = configurator.toClientOptInput();
MockDefaultGenerator generator = new MockDefaultGenerator();
generator.opts(clientOptInput).generate();
DefaultGenerator generator = new DefaultGenerator();
Map<String, String> generatedFiles = generator.getFiles();
Assert.assertEquals(generatedFiles.size(), 14);
generator.setGenerateMetadata(false);
final String someObjFilename = new File(output, "src/main/scala/hello/world/model/SomeObj.scala").getAbsolutePath().replace("\\", "/");
generator.setGeneratorPropertyDefault(CodegenConstants.MODELS, "true");
generator.setGeneratorPropertyDefault(CodegenConstants.MODEL_TESTS, "false");
generator.setGeneratorPropertyDefault(CodegenConstants.MODEL_DOCS, "false");
generator.setGeneratorPropertyDefault(CodegenConstants.APIS, "false");
generator.setGeneratorPropertyDefault(CodegenConstants.SUPPORTING_FILES, "false");
List<File> files = generator.opts(clientOptInput).generate();
Assert.assertEquals(files.size(), 1);
TestUtils.ensureContainsFile(files, output, "src/main/scala/hello/world/model/SomeObj.scala");
File someObj = files.stream().filter(f -> f.getName().equals("SomeObj.scala"))
.findFirst().get();
byte[] fileContents = Files.readAllBytes(someObj.toPath());
Assert.assertEquals(
generatedFiles.get(someObjFilename),
new String(fileContents, StandardCharsets.UTF_8),
Resources.toString(Resources.getResource("codegen/scala/JavaTimeObj.scala.txt"), StandardCharsets.UTF_8));
}
@ -436,18 +465,22 @@ public class ScalaAkkaClientCodegenTest {
.setOutputDir(output.getAbsolutePath().replace("\\", "/"));
final ClientOptInput clientOptInput = configurator.toClientOptInput();
MockDefaultGenerator generator = new MockDefaultGenerator();
DefaultGenerator generator = new DefaultGenerator(false);
generator.setGeneratorPropertyDefault(CodegenConstants.MODELS, "true");
generator.setGeneratorPropertyDefault(CodegenConstants.MODEL_TESTS, "false");
generator.setGeneratorPropertyDefault(CodegenConstants.MODEL_DOCS, "false");
generator.setGeneratorPropertyDefault(CodegenConstants.APIS, "true");
generator.setGeneratorPropertyDefault(CodegenConstants.SUPPORTING_FILES, "true");
Generator gen = generator.opts(clientOptInput);
gen.generate();
List<File> files = gen.generate();
Map<String, String> generatedFiles = generator.getFiles();
Assert.assertEquals(generatedFiles.size(), 14);
Assert.assertEquals(files.size(), 15);
String outputPath = output.getAbsolutePath().replace("\\", "/");
Assert.assertTrue(generatedFiles.containsKey(outputPath + "/src/main/scala/hello/world/model/SomeObj.scala"));
Assert.assertTrue(generatedFiles.containsKey(outputPath + "/src/main/scala/hello/world/core/ApiSettings.scala"));
Assert.assertTrue(generatedFiles.containsKey(outputPath + "/src/main/scala/hello/world/api/PingApi.scala"));
TestUtils.ensureContainsFile(files, output, "src/main/scala/hello/world/model/SomeObj.scala");
TestUtils.ensureContainsFile(files, output, "src/main/scala/hello/world/core/ApiSettings.scala");
TestUtils.ensureContainsFile(files, output, "src/main/scala/hello/world/api/PingApi.scala");
}
@Test(description = "override api packages")
@ -469,17 +502,21 @@ public class ScalaAkkaClientCodegenTest {
.setOutputDir(output.getAbsolutePath().replace("\\", "/"));
final ClientOptInput clientOptInput = configurator.toClientOptInput();
MockDefaultGenerator generator = new MockDefaultGenerator();
DefaultGenerator generator = new DefaultGenerator();
generator.setGeneratorPropertyDefault(CodegenConstants.MODELS, "true");
generator.setGeneratorPropertyDefault(CodegenConstants.MODEL_TESTS, "false");
generator.setGeneratorPropertyDefault(CodegenConstants.MODEL_DOCS, "false");
generator.setGeneratorPropertyDefault(CodegenConstants.APIS, "true");
generator.setGeneratorPropertyDefault(CodegenConstants.SUPPORTING_FILES, "true");
Generator gen = generator.opts(clientOptInput);
gen.generate();
Map<String, String> generatedFiles = generator.getFiles();
Assert.assertEquals(generatedFiles.size(), 14);
List<File> files = gen.generate();
Assert.assertEquals(files.size(), 15);
String outputPath = output.getAbsolutePath().replace("\\", "/");
Assert.assertTrue(generatedFiles.containsKey(outputPath + "/src/main/scala/hello/world/model/package/SomeObj.scala"), "Model package is correct");
Assert.assertTrue(generatedFiles.containsKey(outputPath + "/src/main/scala/hello/world/package/invoker/ApiSettings.scala"), "Invoker package is correct");
Assert.assertTrue(generatedFiles.containsKey(outputPath + "/src/main/scala/hello/world/api/package/PingApi.scala"), "Api package is correct");
TestUtils.ensureContainsFile(files, output, "src/main/scala/hello/world/model/package/SomeObj.scala");
TestUtils.ensureContainsFile(files, output, "src/main/scala/hello/world/package/invoker/ApiSettings.scala");
TestUtils.ensureContainsFile(files, output, "src/main/scala/hello/world/api/package/PingApi.scala");
}
}

View File

@ -18,9 +18,11 @@
package org.openapitools.codegen.yaml;
import org.openapitools.codegen.ClientOptInput;
import org.openapitools.codegen.DefaultGenerator;
import org.openapitools.codegen.MockDefaultGenerator;
import org.openapitools.codegen.TestUtils;
import org.openapitools.codegen.config.CodegenConfigurator;
import org.openapitools.codegen.config.GlobalSettings;
import org.openapitools.codegen.languages.OpenAPIYamlGenerator;
import org.testng.Assert;
import org.testng.annotations.Test;
@ -28,6 +30,7 @@ import org.testng.annotations.Test;
import java.io.File;
import java.nio.file.Files;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
public class YamlGeneratorTest {
@ -45,15 +48,14 @@ public class YamlGeneratorTest {
.setOutputDir(output.getAbsolutePath().replace("\\", "/"));
final ClientOptInput clientOptInput = configurator.toClientOptInput();
MockDefaultGenerator generator = new MockDefaultGenerator();
generator.opts(clientOptInput).generate();
Map<String, String> generatedFiles = generator.getFiles();
Assert.assertEquals(generatedFiles.size(), 4);
TestUtils.ensureContainsFile(generatedFiles, output, "openapi/openapi.yaml");
TestUtils.ensureContainsFile(generatedFiles, output, "README.md");
TestUtils.ensureContainsFile(generatedFiles, output, ".openapi-generator-ignore");
TestUtils.ensureContainsFile(generatedFiles, output, ".openapi-generator/VERSION");
DefaultGenerator generator = new DefaultGenerator();
List<File> files = generator.opts(clientOptInput).generate();
Assert.assertEquals(files.size(), 5);
TestUtils.ensureContainsFile(files, output, "openapi/openapi.yaml");
TestUtils.ensureContainsFile(files, output, "README.md");
TestUtils.ensureContainsFile(files, output, ".openapi-generator-ignore");
TestUtils.ensureContainsFile(files, output, ".openapi-generator/FILES");
TestUtils.ensureContainsFile(files, output, ".openapi-generator/VERSION");
output.deleteOnExit();
}
@ -73,15 +75,15 @@ public class YamlGeneratorTest {
.setOutputDir(output.getAbsolutePath().replace("\\", "/"));
final ClientOptInput clientOptInput = configurator.toClientOptInput();
MockDefaultGenerator generator = new MockDefaultGenerator();
generator.opts(clientOptInput).generate();
DefaultGenerator generator = new DefaultGenerator();
List<File> files = generator.opts(clientOptInput).generate();
Map<String, String> generatedFiles = generator.getFiles();
Assert.assertEquals(generatedFiles.size(), 4);
TestUtils.ensureContainsFile(generatedFiles, output, "ping.yaml");
TestUtils.ensureContainsFile(generatedFiles, output, "README.md");
TestUtils.ensureContainsFile(generatedFiles, output, ".openapi-generator-ignore");
TestUtils.ensureContainsFile(generatedFiles, output, ".openapi-generator/VERSION");
Assert.assertEquals(files.size(), 5);
TestUtils.ensureContainsFile(files, output, "ping.yaml");
TestUtils.ensureContainsFile(files, output, "README.md");
TestUtils.ensureContainsFile(files, output, ".openapi-generator-ignore");
TestUtils.ensureContainsFile(files, output, ".openapi-generator/FILES");
TestUtils.ensureContainsFile(files, output, ".openapi-generator/VERSION");
output.deleteOnExit();
}

View File

@ -0,0 +1,183 @@
<?xml version="1.0" encoding="UTF-8"?>
<jmeterTestPlan version="1.2" properties="2.8" jmeter="2.13 r1665067">
<hashTree>
<TestPlan guiclass="TestPlanGui" testclass="TestPlan" testname="{{classname}} Test Plan via Handlebars" enabled="true">
<stringProp name="TestPlan.comments"></stringProp>
<boolProp name="TestPlan.functional_mode">false</boolProp>
<boolProp name="TestPlan.serialize_threadgroups">false</boolProp>
<elementProp name="TestPlan.user_defined_variables" elementType="Arguments" guiclass="ArgumentsPanel" testclass="Arguments" testname="User Defined Variables" enabled="true">
<collectionProp name="Arguments.arguments"/>
</elementProp>
<stringProp name="TestPlan.user_define_classpath"></stringProp>
</TestPlan>
<hashTree>
<Arguments guiclass="ArgumentsPanel" testclass="Arguments" testname="User Defined Variables" enabled="true">
<collectionProp name="Arguments.arguments">
<elementProp name="threads" elementType="Argument">
<stringProp name="Argument.name">threads</stringProp>
<stringProp name="Argument.value">${__P(threads,1)}</stringProp>
<stringProp name="Argument.metadata">=</stringProp>
</elementProp>
<elementProp name="rampup" elementType="Argument">
<stringProp name="Argument.name">rampup</stringProp>
<stringProp name="Argument.value">${__P(rampup,1)}</stringProp>
<stringProp name="Argument.metadata">=</stringProp>
</elementProp>
<elementProp name="duration" elementType="Argument">
<stringProp name="Argument.name">duration</stringProp>
<stringProp name="Argument.value">${__P(duration,1)}</stringProp>
<stringProp name="Argument.metadata">=</stringProp>
</elementProp>
<elementProp name="testCases" elementType="Argument">
<stringProp name="Argument.name">testCases</stringProp>
<stringProp name="Argument.value">${__P(testCases,10)}</stringProp>
<stringProp name="Argument.metadata">=</stringProp>
</elementProp>
<elementProp name="host" elementType="Argument">
<stringProp name="Argument.name">host</stringProp>
<stringProp name="Argument.value">${__P(host,localhost)}</stringProp>
<stringProp name="Argument.metadata">=</stringProp>
</elementProp>
<elementProp name="port" elementType="Argument">
<stringProp name="Argument.name">port</stringProp>
<stringProp name="Argument.value">${__P(port,8080)}</stringProp>
<stringProp name="Argument.metadata">=</stringProp>
</elementProp>{{#operations}}{{#operation}}
<elementProp name="testData.{{operationId}}File" elementType="Argument">
<stringProp name="Argument.name">testData.{{operationId}}File</stringProp>
<stringProp name="Argument.value">${__P(testData.{{operationId}}File,{{classname}}.csv)}</stringProp>
<stringProp name="Argument.metadata">=</stringProp>
</elementProp>{{/operation}}{{/operations}}
</collectionProp>
</Arguments>
<hashTree/>
<ConfigTestElement guiclass="HttpDefaultsGui" testclass="ConfigTestElement" testname="HTTP Request Defaults" enabled="true">
<elementProp name="HTTPsampler.Arguments" elementType="Arguments" guiclass="HTTPArgumentsPanel" testclass="Arguments" testname="User Defined Variables" enabled="true">
<collectionProp name="Arguments.arguments"/>
</elementProp>
<stringProp name="HTTPSampler.domain">${host}</stringProp>
<stringProp name="HTTPSampler.port">${port}</stringProp>
<stringProp name="HTTPSampler.connect_timeout"></stringProp>
<stringProp name="HTTPSampler.response_timeout"></stringProp>
<stringProp name="HTTPSampler.protocol"></stringProp>
<stringProp name="HTTPSampler.contentEncoding"></stringProp>
<stringProp name="HTTPSampler.path"></stringProp>
<stringProp name="HTTPSampler.concurrentPool">4</stringProp>
</ConfigTestElement>
<hashTree/>
{{#operations}}{{#operation}}<ThreadGroup guiclass="ThreadGroupGui" testclass="ThreadGroup" testname="Thread Group - {{operationId}}" enabled="true">
<stringProp name="ThreadGroup.on_sample_error">continue</stringProp>
<elementProp name="ThreadGroup.main_controller" elementType="LoopController" guiclass="LoopControlPanel" testclass="LoopController" testname="Loop Controller" enabled="true">
<boolProp name="LoopController.continue_forever">false</boolProp>
<stringProp name="LoopController.loops">${testCases}</stringProp>
</elementProp>
<stringProp name="ThreadGroup.num_threads">${threads}</stringProp>
<stringProp name="ThreadGroup.ramp_time">${rampup}</stringProp>
<longProp name="ThreadGroup.start_time">1448391617000</longProp>
<longProp name="ThreadGroup.end_time">1448391617000</longProp>
<boolProp name="ThreadGroup.scheduler">true</boolProp>
<stringProp name="ThreadGroup.duration">${duration}</stringProp>
<stringProp name="ThreadGroup.delay">5</stringProp>
</ThreadGroup>
<hashTree>
<HeaderManager guiclass="HeaderPanel" testclass="HeaderManager" testname="HTTP Header Manager" enabled="true">
<collectionProp name="HeaderManager.headers">{{#headerParams}}
<elementProp name="" elementType="Header">
<stringProp name="Header.name">{{paramName}}</stringProp>
<stringProp name="Header.value">${__RandomString(10,qwertyuiopasdfghjklzxcvbnm)}</stringProp>
</elementProp>{{/headerParams}}
</collectionProp>
</HeaderManager>
<hashTree/>
<HTTPSamplerProxy guiclass="HttpTestSampleGui" testclass="HTTPSamplerProxy" testname="{{operationId}} - ${testCase}" enabled="true">
<elementProp name="HTTPsampler.Arguments" elementType="Arguments" guiclass="HTTPArgumentsPanel" testclass="Arguments" testname="User Defined Variables" enabled="true">
<collectionProp name="Arguments.arguments">{{#queryParams}}
<elementProp name="{{paramName}}" elementType="HTTPArgument">
<boolProp name="HTTPArgument.always_encode">false</boolProp>
{{=<% %>=}}<stringProp name="Argument.value">${<% paramName %>}</stringProp><%={{ }}=%>
<stringProp name="Argument.metadata">=</stringProp>
<boolProp name="HTTPArgument.use_equals">true</boolProp>
<stringProp name="Argument.name">{{paramName}}</stringProp>
</elementProp>{{/queryParams}}
</collectionProp>
</elementProp>
<stringProp name="HTTPSampler.domain"></stringProp>
<stringProp name="HTTPSampler.port"></stringProp>
<stringProp name="HTTPSampler.connect_timeout"></stringProp>
<stringProp name="HTTPSampler.response_timeout"></stringProp>
<stringProp name="HTTPSampler.protocol"></stringProp>
<stringProp name="HTTPSampler.contentEncoding"></stringProp>
<stringProp name="HTTPSampler.path">{{basePathWithoutHost}}{{vendorExtensions.x-path}}</stringProp>
<stringProp name="HTTPSampler.method">{{httpMethod}}</stringProp>
<boolProp name="HTTPSampler.follow_redirects">true</boolProp>
<boolProp name="HTTPSampler.auto_redirects">false</boolProp>
<boolProp name="HTTPSampler.use_keepalive">true</boolProp>
<boolProp name="HTTPSampler.DO_MULTIPART_POST">false</boolProp>
<stringProp name="HTTPSampler.implementation"></stringProp>
<boolProp name="HTTPSampler.monitor">false</boolProp>
<stringProp name="HTTPSampler.embedded_url_re"></stringProp>
<stringProp name="TestPlan.comments">{{summary}} {{notes}}</stringProp>
</HTTPSamplerProxy>
<hashTree>
<CSVDataSet guiclass="TestBeanGUI" testclass="CSVDataSet" testname="Load CSV Test Data - {{operationId}}" enabled="true">
<stringProp name="delimiter">,</stringProp>
<stringProp name="fileEncoding"></stringProp>
<stringProp name="filename">${testData.{{operationId}}File}</stringProp>
<boolProp name="quotedData">true</boolProp>
<boolProp name="recycle">true</boolProp>
<stringProp name="shareMode">shareMode.group</stringProp>
<boolProp name="stopThread">false</boolProp>
<stringProp name="variableNames"></stringProp>
<boolProp name="ignoreFirstLine">true</boolProp>
</CSVDataSet>
<hashTree/>
</hashTree>
<ResponseAssertion guiclass="AssertionGui" testclass="ResponseAssertion" testname="HTTP Status Assertion" enabled="true">
<collectionProp name="Asserion.test_strings">
<stringProp name="812696575">${httpStatusCode}</stringProp>
</collectionProp>
<stringProp name="Assertion.test_field">Assertion.response_code</stringProp>
<boolProp name="Assertion.assume_success">false</boolProp>
<intProp name="Assertion.test_type">8</intProp>
</ResponseAssertion>
<hashTree/>
</hashTree>
{{/operation}}
{{/operations}}
<!-- end of operations -->
<ResultCollector guiclass="ViewResultsFullVisualizer" testclass="ResultCollector" testname="View Results Tree" enabled="true">
<boolProp name="ResultCollector.error_logging">false</boolProp>
<objProp>
<name>saveConfig</name>
<value class="SampleSaveConfiguration">
<time>true</time>
<latency>true</latency>
<timestamp>true</timestamp>
<success>true</success>
<label>true</label>
<code>true</code>
<message>true</message>
<threadName>true</threadName>
<dataType>true</dataType>
<encoding>false</encoding>
<assertions>true</assertions>
<subresults>true</subresults>
<responseData>false</responseData>
<samplerData>false</samplerData>
<xml>false</xml>
<fieldNames>false</fieldNames>
<responseHeaders>false</responseHeaders>
<requestHeaders>false</requestHeaders>
<responseDataOnError>false</responseDataOnError>
<saveAssertionResultsFailureMessage>false</saveAssertionResultsFailureMessage>
<assertionsResultsToSave>0</assertionsResultsToSave>
<bytes>true</bytes>
<threadCounts>true</threadCounts>
</value>
</objProp>
<stringProp name="filename"></stringProp>
</ResultCollector>
<hashTree/>
</hashTree>
</hashTree>
</jmeterTestPlan>

View File

@ -0,0 +1,2 @@
testCase,httpStatusCode{{#each operations}}{{#each .}}{{#if hasParams}},{{/if}}{{#each allParams}}{{paramName}}{{#unless @last}},{{/unless}}{{/each}}{{/each}}{{/each}}
Success,200{{#each operations}}{{#each .}}{{#if hasParams}},{{/if}}{{#each allParams}}0{{#unless @last}},{{/unless}}{{/each}}{{/each}}{{/each}}

Some files were not shown because too many files have changed in this diff Show More