From 31f29be2a026b00b7ed0122a9fb45d057a7aa8fb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pa=C5=ADlo=20Ebermann?= Date: Wed, 15 Mar 2017 10:15:13 +0100 Subject: [PATCH] Use deterministic randomness in ExampleGenerator. (#5068) * Update samples for nodejs + nodejs-google-cloud-functions. * Fix example generator to use deterministic randomness. This avoids changing results after each generation, and makes diff reviews easier. * Update NodeJS samples. This is the last "randomness" update. From now on the samples should only change if either the generator, the input or parameters change. --- .../codegen/examples/ExampleGenerator.java | 12 +- .../.swagger-codegen-ignore | 23 +++ .../api/swagger.yaml | 3 +- .../controllers/Pet.js | 2 - .../controllers/PetService.js | 144 ++++++++++-------- .../controllers/Store.js | 2 - .../controllers/StoreService.js | 81 +++++----- .../controllers/User.js | 2 - .../controllers/UserService.js | 100 ++++++------ .../petstore/nodejs/.swagger-codegen-ignore | 23 +++ .../server/petstore/nodejs/api/swagger.yaml | 6 +- .../petstore/nodejs/controllers/PetService.js | 20 +-- .../nodejs/controllers/StoreService.js | 12 +- .../nodejs/controllers/UserService.js | 4 +- 14 files changed, 254 insertions(+), 180 deletions(-) create mode 100644 samples/server/petstore/nodejs-google-cloud-functions/.swagger-codegen-ignore create mode 100644 samples/server/petstore/nodejs/.swagger-codegen-ignore diff --git a/modules/swagger-codegen/src/main/java/io/swagger/codegen/examples/ExampleGenerator.java b/modules/swagger-codegen/src/main/java/io/swagger/codegen/examples/ExampleGenerator.java index 08a04769e87..08d5065cfd6 100644 --- a/modules/swagger-codegen/src/main/java/io/swagger/codegen/examples/ExampleGenerator.java +++ b/modules/swagger-codegen/src/main/java/io/swagger/codegen/examples/ExampleGenerator.java @@ -32,6 +32,7 @@ import java.util.HashMap; import java.util.HashSet; import java.util.List; import java.util.Map; +import java.util.Random; import java.util.Set; public class ExampleGenerator { @@ -47,9 +48,12 @@ public class ExampleGenerator { private static final String NONE = "none"; protected Map examples; + private Random random; public ExampleGenerator(Map examples) { this.examples = examples; + // use a fixed seed to make the "random" numbers reproducible. + this.random = new Random("ExampleGenerator".hashCode()); } public List> generate(Map examples, List mediaTypes, Property property) { @@ -187,13 +191,13 @@ public class ExampleGenerator { private double randomNumber(Double min, Double max) { if (min != null && max != null) { double range = max - min; - return Math.random() * range + min; + return random.nextDouble() * range + min; } else if (min != null) { - return Math.random() + min; + return random.nextDouble() + min; } else if (max != null) { - return Math.random() * max; + return random.nextDouble() * max; } else { - return Math.random() * 10; + return random.nextDouble() * 10; } } diff --git a/samples/server/petstore/nodejs-google-cloud-functions/.swagger-codegen-ignore b/samples/server/petstore/nodejs-google-cloud-functions/.swagger-codegen-ignore new file mode 100644 index 00000000000..c5fa491b4c5 --- /dev/null +++ b/samples/server/petstore/nodejs-google-cloud-functions/.swagger-codegen-ignore @@ -0,0 +1,23 @@ +# Swagger Codegen Ignore +# Generated by swagger-codegen https://github.com/swagger-api/swagger-codegen + +# Use this file to prevent files from being overwritten by the generator. +# The patterns follow closely to .gitignore or .dockerignore. + +# As an example, the C# client generator defines ApiClient.cs. +# You can make changes and tell Swagger Codgen to ignore just this file by uncommenting the following line: +#ApiClient.cs + +# You can match any string of characters against a directory, file or extension with a single asterisk (*): +#foo/*/qux +# The above matches foo/bar/qux and foo/baz/qux, but not foo/bar/baz/qux + +# You can recursively match patterns against a directory, file or extension with a double asterisk (**): +#foo/**/qux +# This matches foo/bar/qux, foo/baz/qux, and foo/bar/baz/qux + +# You can also negate patterns with an exclamation (!). +# For example, you can ignore all files in a docs folder with the file extension .md: +#docs/*.md +# Then explicitly reverse the ignore rule for a single file: +#!docs/README.md diff --git a/samples/server/petstore/nodejs-google-cloud-functions/api/swagger.yaml b/samples/server/petstore/nodejs-google-cloud-functions/api/swagger.yaml index b47e700ae1f..a2b8cd0f5cc 100644 --- a/samples/server/petstore/nodejs-google-cloud-functions/api/swagger.yaml +++ b/samples/server/petstore/nodejs-google-cloud-functions/api/swagger.yaml @@ -108,11 +108,11 @@ paths: type: "array" items: type: "string" - default: "available" enum: - "available" - "pending" - "sold" + default: "available" collectionFormat: "csv" responses: 200: @@ -385,7 +385,6 @@ paths: description: "ID of the order that needs to be deleted" required: true type: "string" - minimum: 1 responses: 400: description: "Invalid ID supplied" diff --git a/samples/server/petstore/nodejs-google-cloud-functions/controllers/Pet.js b/samples/server/petstore/nodejs-google-cloud-functions/controllers/Pet.js index 3748305bfbe..5ff24c0591f 100644 --- a/samples/server/petstore/nodejs-google-cloud-functions/controllers/Pet.js +++ b/samples/server/petstore/nodejs-google-cloud-functions/controllers/Pet.js @@ -2,10 +2,8 @@ var url = require('url'); - var Pet = require('./PetService'); - module.exports.addPet = function addPet (req, res, next) { Pet.addPet(req.swagger.params, res, next); }; diff --git a/samples/server/petstore/nodejs-google-cloud-functions/controllers/PetService.js b/samples/server/petstore/nodejs-google-cloud-functions/controllers/PetService.js index c8da68c1519..36f34342741 100644 --- a/samples/server/petstore/nodejs-google-cloud-functions/controllers/PetService.js +++ b/samples/server/petstore/nodejs-google-cloud-functions/controllers/PetService.js @@ -2,153 +2,165 @@ exports.addPet = function(args, res, next) { /** - * parameters expected in the args: - * body (Pet) - **/ - // no response value expected for this operation + * Add a new pet to the store + * + * + * body Pet Pet object that needs to be added to the store + * no response value expected for this operation + **/ res.end(); } exports.deletePet = function(args, res, next) { /** - * parameters expected in the args: - * petId (Long) - * api_key (String) - **/ - // no response value expected for this operation + * Deletes a pet + * + * + * petId Long Pet id to delete + * api_key String (optional) + * no response value expected for this operation + **/ res.end(); } exports.findPetsByStatus = function(args, res, next) { /** - * parameters expected in the args: - * status (List) - **/ - var examples = {}; + * Finds Pets by status + * Multiple status values can be provided with comma separated strings + * + * status List Status values that need to be considered for filter + * returns List + **/ + var examples = {}; examples['application/json'] = [ { "photoUrls" : [ "aeiou" ], "name" : "doggie", - "id" : 123456789, + "id" : 0, "category" : { "name" : "aeiou", - "id" : 123456789 + "id" : 6 }, "tags" : [ { "name" : "aeiou", - "id" : 123456789 + "id" : 1 } ], - "status" : "aeiou" + "status" : "available" } ]; - if(Object.keys(examples).length > 0) { + if (Object.keys(examples).length > 0) { res.setHeader('Content-Type', 'application/json'); res.end(JSON.stringify(examples[Object.keys(examples)[0]] || {}, null, 2)); - } - else { + } else { res.end(); } - } exports.findPetsByTags = function(args, res, next) { /** - * parameters expected in the args: - * tags (List) - **/ - var examples = {}; + * Finds Pets by tags + * Multiple tags can be provided with comma separated strings. Use tag1, tag2, tag3 for testing. + * + * tags List Tags to filter by + * returns List + **/ + var examples = {}; examples['application/json'] = [ { "photoUrls" : [ "aeiou" ], "name" : "doggie", - "id" : 123456789, + "id" : 0, "category" : { "name" : "aeiou", - "id" : 123456789 + "id" : 6 }, "tags" : [ { "name" : "aeiou", - "id" : 123456789 + "id" : 1 } ], - "status" : "aeiou" + "status" : "available" } ]; - if(Object.keys(examples).length > 0) { + if (Object.keys(examples).length > 0) { res.setHeader('Content-Type', 'application/json'); res.end(JSON.stringify(examples[Object.keys(examples)[0]] || {}, null, 2)); - } - else { + } else { res.end(); } - } exports.getPetById = function(args, res, next) { /** - * parameters expected in the args: - * petId (Long) - **/ - var examples = {}; + * Find pet by ID + * Returns a single pet + * + * petId Long ID of pet to return + * returns Pet + **/ + var examples = {}; examples['application/json'] = { "photoUrls" : [ "aeiou" ], "name" : "doggie", - "id" : 123456789, + "id" : 0, "category" : { "name" : "aeiou", - "id" : 123456789 + "id" : 6 }, "tags" : [ { "name" : "aeiou", - "id" : 123456789 + "id" : 1 } ], - "status" : "aeiou" + "status" : "available" }; - if(Object.keys(examples).length > 0) { + if (Object.keys(examples).length > 0) { res.setHeader('Content-Type', 'application/json'); res.end(JSON.stringify(examples[Object.keys(examples)[0]] || {}, null, 2)); - } - else { + } else { res.end(); } - } exports.updatePet = function(args, res, next) { /** - * parameters expected in the args: - * body (Pet) - **/ - // no response value expected for this operation + * Update an existing pet + * + * + * body Pet Pet object that needs to be added to the store + * no response value expected for this operation + **/ res.end(); } exports.updatePetWithForm = function(args, res, next) { /** - * parameters expected in the args: - * petId (Long) - * name (String) - * status (String) - **/ - // no response value expected for this operation + * Updates a pet in the store with form data + * + * + * petId Long ID of pet that needs to be updated + * name String Updated name of the pet (optional) + * status String Updated status of the pet (optional) + * no response value expected for this operation + **/ res.end(); } exports.uploadFile = function(args, res, next) { /** - * parameters expected in the args: - * petId (Long) - * additionalMetadata (String) - * file (File) - **/ - var examples = {}; + * uploads an image + * + * + * petId Long ID of pet to update + * additionalMetadata String Additional data to pass to server (optional) + * file File file to upload (optional) + * returns ApiResponse + **/ + var examples = {}; examples['application/json'] = { - "code" : 123, + "code" : 0, "type" : "aeiou", "message" : "aeiou" }; - if(Object.keys(examples).length > 0) { + if (Object.keys(examples).length > 0) { res.setHeader('Content-Type', 'application/json'); res.end(JSON.stringify(examples[Object.keys(examples)[0]] || {}, null, 2)); - } - else { + } else { res.end(); } - } diff --git a/samples/server/petstore/nodejs-google-cloud-functions/controllers/Store.js b/samples/server/petstore/nodejs-google-cloud-functions/controllers/Store.js index ac67c740d29..94d86b7b590 100644 --- a/samples/server/petstore/nodejs-google-cloud-functions/controllers/Store.js +++ b/samples/server/petstore/nodejs-google-cloud-functions/controllers/Store.js @@ -2,10 +2,8 @@ var url = require('url'); - var Store = require('./StoreService'); - module.exports.deleteOrder = function deleteOrder (req, res, next) { Store.deleteOrder(req.swagger.params, res, next); }; diff --git a/samples/server/petstore/nodejs-google-cloud-functions/controllers/StoreService.js b/samples/server/petstore/nodejs-google-cloud-functions/controllers/StoreService.js index aed5113a915..be99ec7acbc 100644 --- a/samples/server/petstore/nodejs-google-cloud-functions/controllers/StoreService.js +++ b/samples/server/petstore/nodejs-google-cloud-functions/controllers/StoreService.js @@ -2,76 +2,81 @@ exports.deleteOrder = function(args, res, next) { /** - * parameters expected in the args: - * orderId (String) - **/ - // no response value expected for this operation + * Delete purchase order by ID + * For valid response try integer IDs with value < 1000. Anything above 1000 or nonintegers will generate API errors + * + * orderId String ID of the order that needs to be deleted + * no response value expected for this operation + **/ res.end(); } exports.getInventory = function(args, res, next) { /** - * parameters expected in the args: - **/ - var examples = {}; + * Returns pet inventories by status + * Returns a map of status codes to quantities + * + * returns Map + **/ + var examples = {}; examples['application/json'] = { - "key" : 123 + "key" : 0 }; - if(Object.keys(examples).length > 0) { + if (Object.keys(examples).length > 0) { res.setHeader('Content-Type', 'application/json'); res.end(JSON.stringify(examples[Object.keys(examples)[0]] || {}, null, 2)); - } - else { + } else { res.end(); } - } exports.getOrderById = function(args, res, next) { /** - * parameters expected in the args: - * orderId (Long) - **/ - var examples = {}; + * Find purchase order by ID + * For valid response try integer IDs with value <= 5 or > 10. Other values will generated exceptions + * + * orderId Long ID of pet that needs to be fetched + * returns Order + **/ + var examples = {}; examples['application/json'] = { - "petId" : 123456789, - "quantity" : 123, - "id" : 123456789, + "petId" : 6, + "quantity" : 1, + "id" : 0, "shipDate" : "2000-01-23T04:56:07.000+00:00", - "complete" : true, - "status" : "aeiou" + "complete" : false, + "status" : "placed" }; - if(Object.keys(examples).length > 0) { + if (Object.keys(examples).length > 0) { res.setHeader('Content-Type', 'application/json'); res.end(JSON.stringify(examples[Object.keys(examples)[0]] || {}, null, 2)); - } - else { + } else { res.end(); } - } exports.placeOrder = function(args, res, next) { /** - * parameters expected in the args: - * body (Order) - **/ - var examples = {}; + * Place an order for a pet + * + * + * body Order order placed for purchasing the pet + * returns Order + **/ + var examples = {}; examples['application/json'] = { - "petId" : 123456789, - "quantity" : 123, - "id" : 123456789, + "petId" : 6, + "quantity" : 1, + "id" : 0, "shipDate" : "2000-01-23T04:56:07.000+00:00", - "complete" : true, - "status" : "aeiou" + "complete" : false, + "status" : "placed" }; - if(Object.keys(examples).length > 0) { + if (Object.keys(examples).length > 0) { res.setHeader('Content-Type', 'application/json'); res.end(JSON.stringify(examples[Object.keys(examples)[0]] || {}, null, 2)); - } - else { + } else { res.end(); } - } diff --git a/samples/server/petstore/nodejs-google-cloud-functions/controllers/User.js b/samples/server/petstore/nodejs-google-cloud-functions/controllers/User.js index bac1d7f6a88..4b118e8211d 100644 --- a/samples/server/petstore/nodejs-google-cloud-functions/controllers/User.js +++ b/samples/server/petstore/nodejs-google-cloud-functions/controllers/User.js @@ -2,10 +2,8 @@ var url = require('url'); - var User = require('./UserService'); - module.exports.createUser = function createUser (req, res, next) { User.createUser(req.swagger.params, res, next); }; diff --git a/samples/server/petstore/nodejs-google-cloud-functions/controllers/UserService.js b/samples/server/petstore/nodejs-google-cloud-functions/controllers/UserService.js index 3a62feeaf3f..d15268eee68 100644 --- a/samples/server/petstore/nodejs-google-cloud-functions/controllers/UserService.js +++ b/samples/server/petstore/nodejs-google-cloud-functions/controllers/UserService.js @@ -2,99 +2,113 @@ exports.createUser = function(args, res, next) { /** - * parameters expected in the args: - * body (User) - **/ - // no response value expected for this operation + * Create user + * This can only be done by the logged in user. + * + * body User Created user object + * no response value expected for this operation + **/ res.end(); } exports.createUsersWithArrayInput = function(args, res, next) { /** - * parameters expected in the args: - * body (List) - **/ - // no response value expected for this operation + * Creates list of users with given input array + * + * + * body List List of user object + * no response value expected for this operation + **/ res.end(); } exports.createUsersWithListInput = function(args, res, next) { /** - * parameters expected in the args: - * body (List) - **/ - // no response value expected for this operation + * Creates list of users with given input array + * + * + * body List List of user object + * no response value expected for this operation + **/ res.end(); } exports.deleteUser = function(args, res, next) { /** - * parameters expected in the args: - * username (String) - **/ - // no response value expected for this operation + * Delete user + * This can only be done by the logged in user. + * + * username String The name that needs to be deleted + * no response value expected for this operation + **/ res.end(); } exports.getUserByName = function(args, res, next) { /** - * parameters expected in the args: - * username (String) - **/ - var examples = {}; + * Get user by user name + * + * + * username String The name that needs to be fetched. Use user1 for testing. + * returns User + **/ + var examples = {}; examples['application/json'] = { "firstName" : "aeiou", "lastName" : "aeiou", "password" : "aeiou", - "userStatus" : 123, + "userStatus" : 6, "phone" : "aeiou", - "id" : 123456789, + "id" : 0, "email" : "aeiou", "username" : "aeiou" }; - if(Object.keys(examples).length > 0) { + if (Object.keys(examples).length > 0) { res.setHeader('Content-Type', 'application/json'); res.end(JSON.stringify(examples[Object.keys(examples)[0]] || {}, null, 2)); - } - else { + } else { res.end(); } - } exports.loginUser = function(args, res, next) { /** - * parameters expected in the args: - * username (String) - * password (String) - **/ - var examples = {}; + * Logs user into the system + * + * + * username String The user name for login + * password String The password for login in clear text + * returns String + **/ + var examples = {}; examples['application/json'] = "aeiou"; - if(Object.keys(examples).length > 0) { + if (Object.keys(examples).length > 0) { res.setHeader('Content-Type', 'application/json'); res.end(JSON.stringify(examples[Object.keys(examples)[0]] || {}, null, 2)); - } - else { + } else { res.end(); } - } exports.logoutUser = function(args, res, next) { /** - * parameters expected in the args: - **/ - // no response value expected for this operation + * Logs out current logged in user session + * + * + * no response value expected for this operation + **/ res.end(); } exports.updateUser = function(args, res, next) { /** - * parameters expected in the args: - * username (String) - * body (User) - **/ - // no response value expected for this operation + * Updated user + * This can only be done by the logged in user. + * + * username String name that need to be deleted + * body User Updated user object + * no response value expected for this operation + **/ res.end(); } diff --git a/samples/server/petstore/nodejs/.swagger-codegen-ignore b/samples/server/petstore/nodejs/.swagger-codegen-ignore new file mode 100644 index 00000000000..c5fa491b4c5 --- /dev/null +++ b/samples/server/petstore/nodejs/.swagger-codegen-ignore @@ -0,0 +1,23 @@ +# Swagger Codegen Ignore +# Generated by swagger-codegen https://github.com/swagger-api/swagger-codegen + +# Use this file to prevent files from being overwritten by the generator. +# The patterns follow closely to .gitignore or .dockerignore. + +# As an example, the C# client generator defines ApiClient.cs. +# You can make changes and tell Swagger Codgen to ignore just this file by uncommenting the following line: +#ApiClient.cs + +# You can match any string of characters against a directory, file or extension with a single asterisk (*): +#foo/*/qux +# The above matches foo/bar/qux and foo/baz/qux, but not foo/bar/baz/qux + +# You can recursively match patterns against a directory, file or extension with a double asterisk (**): +#foo/**/qux +# This matches foo/bar/qux, foo/baz/qux, and foo/bar/baz/qux + +# You can also negate patterns with an exclamation (!). +# For example, you can ignore all files in a docs folder with the file extension .md: +#docs/*.md +# Then explicitly reverse the ignore rule for a single file: +#!docs/README.md diff --git a/samples/server/petstore/nodejs/api/swagger.yaml b/samples/server/petstore/nodejs/api/swagger.yaml index 3be49fdd5f2..a2b8cd0f5cc 100644 --- a/samples/server/petstore/nodejs/api/swagger.yaml +++ b/samples/server/petstore/nodejs/api/swagger.yaml @@ -108,11 +108,11 @@ paths: type: "array" items: type: "string" - default: "available" enum: - "available" - "pending" - "sold" + default: "available" collectionFormat: "csv" responses: 200: @@ -356,8 +356,8 @@ paths: description: "ID of pet that needs to be fetched" required: true type: "integer" - maximum: 5.0 - minimum: 1.0 + maximum: 5 + minimum: 1 format: "int64" responses: 200: diff --git a/samples/server/petstore/nodejs/controllers/PetService.js b/samples/server/petstore/nodejs/controllers/PetService.js index b0a9f8edacc..36f34342741 100644 --- a/samples/server/petstore/nodejs/controllers/PetService.js +++ b/samples/server/petstore/nodejs/controllers/PetService.js @@ -35,14 +35,14 @@ exports.findPetsByStatus = function(args, res, next) { examples['application/json'] = [ { "photoUrls" : [ "aeiou" ], "name" : "doggie", - "id" : 1, + "id" : 0, "category" : { "name" : "aeiou", - "id" : 7 + "id" : 6 }, "tags" : [ { "name" : "aeiou", - "id" : 2 + "id" : 1 } ], "status" : "available" } ]; @@ -66,14 +66,14 @@ exports.findPetsByTags = function(args, res, next) { examples['application/json'] = [ { "photoUrls" : [ "aeiou" ], "name" : "doggie", - "id" : 9, + "id" : 0, "category" : { "name" : "aeiou", - "id" : 7 + "id" : 6 }, "tags" : [ { "name" : "aeiou", - "id" : 4 + "id" : 1 } ], "status" : "available" } ]; @@ -97,14 +97,14 @@ exports.getPetById = function(args, res, next) { examples['application/json'] = { "photoUrls" : [ "aeiou" ], "name" : "doggie", - "id" : 4, + "id" : 0, "category" : { "name" : "aeiou", - "id" : 4 + "id" : 6 }, "tags" : [ { "name" : "aeiou", - "id" : 4 + "id" : 1 } ], "status" : "available" }; @@ -152,7 +152,7 @@ exports.uploadFile = function(args, res, next) { **/ var examples = {}; examples['application/json'] = { - "code" : 7, + "code" : 0, "type" : "aeiou", "message" : "aeiou" }; diff --git a/samples/server/petstore/nodejs/controllers/StoreService.js b/samples/server/petstore/nodejs/controllers/StoreService.js index ec122dc6368..be99ec7acbc 100644 --- a/samples/server/petstore/nodejs/controllers/StoreService.js +++ b/samples/server/petstore/nodejs/controllers/StoreService.js @@ -40,9 +40,9 @@ exports.getOrderById = function(args, res, next) { **/ var examples = {}; examples['application/json'] = { - "petId" : 2, - "quantity" : 9, - "id" : 5, + "petId" : 6, + "quantity" : 1, + "id" : 0, "shipDate" : "2000-01-23T04:56:07.000+00:00", "complete" : false, "status" : "placed" @@ -65,9 +65,9 @@ exports.placeOrder = function(args, res, next) { **/ var examples = {}; examples['application/json'] = { - "petId" : 5, - "quantity" : 5, - "id" : 1, + "petId" : 6, + "quantity" : 1, + "id" : 0, "shipDate" : "2000-01-23T04:56:07.000+00:00", "complete" : false, "status" : "placed" diff --git a/samples/server/petstore/nodejs/controllers/UserService.js b/samples/server/petstore/nodejs/controllers/UserService.js index 762b3455f61..d15268eee68 100644 --- a/samples/server/petstore/nodejs/controllers/UserService.js +++ b/samples/server/petstore/nodejs/controllers/UserService.js @@ -57,9 +57,9 @@ exports.getUserByName = function(args, res, next) { "firstName" : "aeiou", "lastName" : "aeiou", "password" : "aeiou", - "userStatus" : 4, + "userStatus" : 6, "phone" : "aeiou", - "id" : 5, + "id" : 0, "email" : "aeiou", "username" : "aeiou" };