From e38fc2c3daeb119235b5cf88d5389bd7fc2ae938 Mon Sep 17 00:00:00 2001 From: xhh Date: Fri, 12 Jun 2015 20:15:48 +0800 Subject: [PATCH 1/9] Deserialize response for "object" type in Ruby client --- .../codegen/languages/RubyClientCodegen.java | 25 ++++--- .../src/main/resources/ruby/api.mustache | 4 +- .../main/resources/ruby/base_object.mustache | 10 +-- .../resources/ruby/swagger/response.mustache | 68 +++++++++++++++---- 4 files changed, 78 insertions(+), 29 deletions(-) diff --git a/modules/swagger-codegen/src/main/java/io/swagger/codegen/languages/RubyClientCodegen.java b/modules/swagger-codegen/src/main/java/io/swagger/codegen/languages/RubyClientCodegen.java index 01fe6c6eed45..2ee227fea29c 100644 --- a/modules/swagger-codegen/src/main/java/io/swagger/codegen/languages/RubyClientCodegen.java +++ b/modules/swagger-codegen/src/main/java/io/swagger/codegen/languages/RubyClientCodegen.java @@ -48,12 +48,21 @@ public class RubyClientCodegen extends DefaultCodegen implements CodegenConfig { languageSpecificPrimitives.add("string"); languageSpecificPrimitives.add("DateTime"); - typeMapping.put("long", "int"); - typeMapping.put("integer", "int"); - typeMapping.put("Array", "array"); - typeMapping.put("String", "string"); - typeMapping.put("List", "array"); - typeMapping.put("map", "map"); + typeMapping.put("string", "String"); + typeMapping.put("char", "String"); + typeMapping.put("int", "Integer"); + typeMapping.put("integer", "Integer"); + typeMapping.put("long", "Integer"); + typeMapping.put("short", "Integer"); + typeMapping.put("float", "Float"); + typeMapping.put("double", "Float"); + typeMapping.put("number", "Float"); + typeMapping.put("DateTime", "DateTime"); + typeMapping.put("boolean", "BOOLEAN"); + typeMapping.put("array", "Array"); + typeMapping.put("List", "Array"); + typeMapping.put("map", "Hash"); + typeMapping.put("object", "Hash"); String baseFolder = "lib" + File.separatorChar + gemName; String swaggerFolder = baseFolder + File.separatorChar + "swagger"; @@ -107,11 +116,11 @@ public class RubyClientCodegen extends DefaultCodegen implements CodegenConfig { if (p instanceof ArrayProperty) { ArrayProperty ap = (ArrayProperty) p; Property inner = ap.getItems(); - return getSwaggerType(p) + "[" + getTypeDeclaration(inner) + "]"; + return getSwaggerType(p) + "<" + getTypeDeclaration(inner) + ">"; } else if (p instanceof MapProperty) { MapProperty mp = (MapProperty) p; Property inner = mp.getAdditionalProperties(); - return getSwaggerType(p) + "[string," + getTypeDeclaration(inner) + "]"; + return getSwaggerType(p) + ""; } return super.getTypeDeclaration(p); } diff --git a/modules/swagger-codegen/src/main/resources/ruby/api.mustache b/modules/swagger-codegen/src/main/resources/ruby/api.mustache index 3e1ac14014ef..2b0f17c63f72 100644 --- a/modules/swagger-codegen/src/main/resources/ruby/api.mustache +++ b/modules/swagger-codegen/src/main/resources/ruby/api.mustache @@ -51,8 +51,8 @@ module {{moduleName}} {{/bodyParam}} auth_names = [{{#authMethods}}'{{name}}'{{#hasMore}}, {{/hasMore}}{{/authMethods}}] - {{#returnType}}response = Swagger::Request.new(:{{httpMethod}}, path, {:params => query_params, :headers => header_params, :form_params => form_params, :body => post_body, :auth_names => auth_names}).make.body - {{#returnContainer}}response.map {|response| {{/returnContainer}}obj = {{returnBaseType}}.new() and obj.build_from_hash(response){{#returnContainer}} }{{/returnContainer}}{{/returnType}}{{^returnType}}Swagger::Request.new(:{{httpMethod}}, path, {:params => query_params,:headers => header_params, :form_params => form_params, :body => post_body, :auth_names => auth_names}).make + {{#returnType}}response = Swagger::Request.new(:{{httpMethod}}, path, {:params => query_params, :headers => header_params, :form_params => form_params, :body => post_body, :auth_names => auth_names}).make + response.deserialize('{{{returnType}}}'){{/returnType}}{{^returnType}}Swagger::Request.new(:{{httpMethod}}, path, {:params => query_params,:headers => header_params, :form_params => form_params, :body => post_body, :auth_names => auth_names}).make nil{{/returnType}} end {{/operation}} diff --git a/modules/swagger-codegen/src/main/resources/ruby/base_object.mustache b/modules/swagger-codegen/src/main/resources/ruby/base_object.mustache index c0e563a0bb72..2f1e1064a5be 100644 --- a/modules/swagger-codegen/src/main/resources/ruby/base_object.mustache +++ b/modules/swagger-codegen/src/main/resources/ruby/base_object.mustache @@ -15,7 +15,7 @@ module {{moduleName}} def build_from_hash(attributes) return nil unless attributes.is_a?(Hash) self.class.swagger_types.each_pair do |key, type| - if type =~ /^array\[(.*)\]/i + if type =~ /^Array<(.*)>/i if attributes[self.class.attribute_map[key]].is_a?(Array) self.send("#{key}=", attributes[self.class.attribute_map[key]].map{ |v| _deserialize($1, v) } ) else @@ -35,13 +35,13 @@ module {{moduleName}} case type.to_sym when :DateTime DateTime.parse(value) - when :string + when :String value.to_s - when :int + when :Integer value.to_i - when :double + when :Float value.to_f - when :boolean + when :BOOLEAN if value =~ /^(true|t|yes|y|1)$/i true else diff --git a/modules/swagger-codegen/src/main/resources/ruby/swagger/response.mustache b/modules/swagger-codegen/src/main/resources/ruby/swagger/response.mustache index e7bb482fb663..3abc7df40d7a 100644 --- a/modules/swagger-codegen/src/main/resources/ruby/swagger/response.mustache +++ b/modules/swagger-codegen/src/main/resources/ruby/swagger/response.mustache @@ -2,6 +2,7 @@ module {{moduleName}} module Swagger class Response require 'json' + require 'date' attr_accessor :raw @@ -9,8 +10,8 @@ module {{moduleName}} self.raw = raw case self.code - when 500..510 then raise(ServerError, self.error_message) - when 299..426 then raise(ClientError, self.error_message) + when 500..510 then raise(ServerError, self.body) + when 299..426 then raise(ClientError, self.body) end end @@ -18,19 +19,58 @@ module {{moduleName}} raw.code end - # Account for error messages that take different forms... - def error_message - body['message'] - rescue - body + def body + raw.body end - # If body is JSON, parse it - # Otherwise return raw string - def body - JSON.parse(raw.body, :symbolize_names => true) - rescue - raw.body + # Deserialize the raw response body to the given return type. + # + # @param [String] return_type some examples: "User", "Array[User]", "Hash[String,Integer]" + def deserialize(return_type) + return nil if body.blank? + + # ensuring a default content type + content_type = raw.headers_hash['Content-Type'] || 'application/json' + + unless content_type.start_with?('application/json') + fail "Content-Type is not supported: #{content_type}" + end + + begin + data = JSON.parse(body, :symbolize_names => true) + rescue JSON::ParserError => e + if return_type == 'String' + return body + else + raise e + end + end + + build_models data, return_type + end + + # Build model(s) from Hash data for array/hash values of the response. + def build_models(data, return_type) + case return_type + when /\AArray<(.+)>\z/ + sub_type = $1 + data.map {|item| build_models(item, sub_type) } + when /\AHash\\z/ + sub_type = $1 + {}.tap do |hash| + data.each {|k, v| hash[k] = build_models(v, sub_type) } + end + when 'String', 'Integer', 'Float', 'BOOLEAN' + # primitives, return directly + data + when 'DateTime' + DateTime.parse data + else + # models + {{moduleName}}.const_get(return_type).new.tap do |model| + model.build_from_hash data + end + end end # `headers_hash` is a Typhoeus-specific extension of Hash, @@ -58,7 +98,7 @@ module {{moduleName}} def pretty_body return unless body.present? case format - when 'json' then JSON.pretty_generate(body).gsub(/\n/, '
') + when 'json' then JSON.pretty_generate(JSON.parse(body)).gsub(/\n/, '
') end end From 4c8c6c3880748ad9bcf3a692ba9c17b18ae93801 Mon Sep 17 00:00:00 2001 From: xhh Date: Fri, 12 Jun 2015 20:18:50 +0800 Subject: [PATCH 2/9] Rebuild Ruby Petstore sample --- .../src/main/resources/ruby/api.mustache | 2 +- .../petstore/ruby/lib/swagger_client.rb | 2 +- .../ruby/lib/swagger_client/api/pet_api.rb | 30 ++++---- .../ruby/lib/swagger_client/api/store_api.rb | 14 ++-- .../ruby/lib/swagger_client/api/user_api.rb | 18 ++--- .../lib/swagger_client/models/base_object.rb | 10 +-- .../lib/swagger_client/models/category.rb | 4 +- .../ruby/lib/swagger_client/models/order.rb | 10 +-- .../ruby/lib/swagger_client/models/pet.rb | 10 +-- .../ruby/lib/swagger_client/models/tag.rb | 4 +- .../ruby/lib/swagger_client/models/user.rb | 16 ++--- .../lib/swagger_client/swagger/response.rb | 68 +++++++++++++++---- 12 files changed, 114 insertions(+), 74 deletions(-) diff --git a/modules/swagger-codegen/src/main/resources/ruby/api.mustache b/modules/swagger-codegen/src/main/resources/ruby/api.mustache index 2b0f17c63f72..531f8710e696 100644 --- a/modules/swagger-codegen/src/main/resources/ruby/api.mustache +++ b/modules/swagger-codegen/src/main/resources/ruby/api.mustache @@ -11,7 +11,7 @@ module {{moduleName}} # {{notes}} {{#allParams}}{{#required}} # @param {{paramName}} {{description}} {{/required}}{{/allParams}} # @param [Hash] opts the optional parameters -{{#allParams}}{{^required}} # @option opts [{{dataType}}] :{{paramName}} {{description}} +{{#allParams}}{{^required}} # @option opts [{{{dataType}}}] :{{paramName}} {{description}} {{/required}}{{/allParams}} # @return [{{#returnType}}{{{returnType}}}{{/returnType}}{{^returnType}}nil{{/returnType}}] def self.{{nickname}}({{#allParams}}{{#required}}{{paramName}}, {{/required}}{{/allParams}}opts = {}) {{#allParams}}{{#required}} diff --git a/samples/client/petstore/ruby/lib/swagger_client.rb b/samples/client/petstore/ruby/lib/swagger_client.rb index 998658c8b6e4..6d239185005c 100644 --- a/samples/client/petstore/ruby/lib/swagger_client.rb +++ b/samples/client/petstore/ruby/lib/swagger_client.rb @@ -16,8 +16,8 @@ require 'swagger_client/models/order' # APIs require 'swagger_client/api/user_api' -require 'swagger_client/api/store_api' require 'swagger_client/api/pet_api' +require 'swagger_client/api/store_api' module SwaggerClient # Initialize the default configuration diff --git a/samples/client/petstore/ruby/lib/swagger_client/api/pet_api.rb b/samples/client/petstore/ruby/lib/swagger_client/api/pet_api.rb index 2ce4fb04ecd6..4a421faef86a 100644 --- a/samples/client/petstore/ruby/lib/swagger_client/api/pet_api.rb +++ b/samples/client/petstore/ruby/lib/swagger_client/api/pet_api.rb @@ -82,8 +82,8 @@ module SwaggerClient # Finds Pets by status # Multiple status values can be provided with comma seperated strings # @param [Hash] opts the optional parameters - # @option opts [array[string]] :status Status values that need to be considered for filter - # @return [array[Pet]] + # @option opts [Array] :status Status values that need to be considered for filter + # @return [Array] def self.find_pets_by_status(opts = {}) @@ -113,15 +113,15 @@ module SwaggerClient auth_names = ['petstore_auth'] - response = Swagger::Request.new(:GET, path, {:params => query_params, :headers => header_params, :form_params => form_params, :body => post_body, :auth_names => auth_names}).make.body - response.map {|response| obj = Pet.new() and obj.build_from_hash(response) } + response = Swagger::Request.new(:GET, path, {:params => query_params, :headers => header_params, :form_params => form_params, :body => post_body, :auth_names => auth_names}).make + response.deserialize('Array') end # Finds Pets by tags # Muliple tags can be provided with comma seperated strings. Use tag1, tag2, tag3 for testing. # @param [Hash] opts the optional parameters - # @option opts [array[string]] :tags Tags to filter by - # @return [array[Pet]] + # @option opts [Array] :tags Tags to filter by + # @return [Array] def self.find_pets_by_tags(opts = {}) @@ -151,8 +151,8 @@ module SwaggerClient auth_names = ['petstore_auth'] - response = Swagger::Request.new(:GET, path, {:params => query_params, :headers => header_params, :form_params => form_params, :body => post_body, :auth_names => auth_names}).make.body - response.map {|response| obj = Pet.new() and obj.build_from_hash(response) } + response = Swagger::Request.new(:GET, path, {:params => query_params, :headers => header_params, :form_params => form_params, :body => post_body, :auth_names => auth_names}).make + response.deserialize('Array') end # Find pet by ID @@ -190,17 +190,17 @@ module SwaggerClient post_body = nil - auth_names = ['petstore_auth', 'api_key'] - response = Swagger::Request.new(:GET, path, {:params => query_params, :headers => header_params, :form_params => form_params, :body => post_body, :auth_names => auth_names}).make.body - obj = Pet.new() and obj.build_from_hash(response) + auth_names = ['api_key', 'petstore_auth'] + response = Swagger::Request.new(:GET, path, {:params => query_params, :headers => header_params, :form_params => form_params, :body => post_body, :auth_names => auth_names}).make + response.deserialize('Pet') end # Updates a pet in the store with form data # # @param pet_id ID of pet that needs to be updated # @param [Hash] opts the optional parameters - # @option opts [string] :name Updated name of the pet - # @option opts [string] :status Updated status of the pet + # @option opts [String] :name Updated name of the pet + # @option opts [String] :status Updated status of the pet # @return [nil] def self.update_pet_with_form(pet_id, opts = {}) @@ -243,7 +243,7 @@ module SwaggerClient # # @param pet_id Pet id to delete # @param [Hash] opts the optional parameters - # @option opts [string] :api_key + # @option opts [String] :api_key # @return [nil] def self.delete_pet(pet_id, opts = {}) @@ -285,7 +285,7 @@ module SwaggerClient # # @param pet_id ID of pet to update # @param [Hash] opts the optional parameters - # @option opts [string] :additional_metadata Additional data to pass to server + # @option opts [String] :additional_metadata Additional data to pass to server # @option opts [file] :file file to upload # @return [nil] def self.upload_file(pet_id, opts = {}) diff --git a/samples/client/petstore/ruby/lib/swagger_client/api/store_api.rb b/samples/client/petstore/ruby/lib/swagger_client/api/store_api.rb index 010d170945be..a97f981f878f 100644 --- a/samples/client/petstore/ruby/lib/swagger_client/api/store_api.rb +++ b/samples/client/petstore/ruby/lib/swagger_client/api/store_api.rb @@ -8,7 +8,7 @@ module SwaggerClient # Returns pet inventories by status # Returns a map of status codes to quantities # @param [Hash] opts the optional parameters - # @return [map[string,int]] + # @return [Hash] def self.get_inventory(opts = {}) @@ -37,8 +37,8 @@ module SwaggerClient auth_names = ['api_key'] - response = Swagger::Request.new(:GET, path, {:params => query_params, :headers => header_params, :form_params => form_params, :body => post_body, :auth_names => auth_names}).make.body - response.map {|response| obj = map.new() and obj.build_from_hash(response) } + response = Swagger::Request.new(:GET, path, {:params => query_params, :headers => header_params, :form_params => form_params, :body => post_body, :auth_names => auth_names}).make + response.deserialize('Hash') end # Place an order for a pet @@ -74,8 +74,8 @@ module SwaggerClient auth_names = [] - response = Swagger::Request.new(:POST, path, {:params => query_params, :headers => header_params, :form_params => form_params, :body => post_body, :auth_names => auth_names}).make.body - obj = Order.new() and obj.build_from_hash(response) + response = Swagger::Request.new(:POST, path, {:params => query_params, :headers => header_params, :form_params => form_params, :body => post_body, :auth_names => auth_names}).make + response.deserialize('Order') end # Find purchase order by ID @@ -114,8 +114,8 @@ module SwaggerClient auth_names = [] - response = Swagger::Request.new(:GET, path, {:params => query_params, :headers => header_params, :form_params => form_params, :body => post_body, :auth_names => auth_names}).make.body - obj = Order.new() and obj.build_from_hash(response) + response = Swagger::Request.new(:GET, path, {:params => query_params, :headers => header_params, :form_params => form_params, :body => post_body, :auth_names => auth_names}).make + response.deserialize('Order') end # Delete purchase order by ID diff --git a/samples/client/petstore/ruby/lib/swagger_client/api/user_api.rb b/samples/client/petstore/ruby/lib/swagger_client/api/user_api.rb index a3a57503b017..8337a8b9dd0f 100644 --- a/samples/client/petstore/ruby/lib/swagger_client/api/user_api.rb +++ b/samples/client/petstore/ruby/lib/swagger_client/api/user_api.rb @@ -45,7 +45,7 @@ module SwaggerClient # Creates list of users with given input array # # @param [Hash] opts the optional parameters - # @option opts [array[User]] :body List of user object + # @option opts [Array] :body List of user object # @return [nil] def self.create_users_with_array_input(opts = {}) @@ -82,7 +82,7 @@ module SwaggerClient # Creates list of users with given input array # # @param [Hash] opts the optional parameters - # @option opts [array[User]] :body List of user object + # @option opts [Array] :body List of user object # @return [nil] def self.create_users_with_list_input(opts = {}) @@ -119,9 +119,9 @@ module SwaggerClient # Logs user into the system # # @param [Hash] opts the optional parameters - # @option opts [string] :username The user name for login - # @option opts [string] :password The password for login in clear text - # @return [string] + # @option opts [String] :username The user name for login + # @option opts [String] :password The password for login in clear text + # @return [String] def self.login_user(opts = {}) @@ -152,8 +152,8 @@ module SwaggerClient auth_names = [] - response = Swagger::Request.new(:GET, path, {:params => query_params, :headers => header_params, :form_params => form_params, :body => post_body, :auth_names => auth_names}).make.body - obj = string.new() and obj.build_from_hash(response) + response = Swagger::Request.new(:GET, path, {:params => query_params, :headers => header_params, :form_params => form_params, :body => post_body, :auth_names => auth_names}).make + response.deserialize('String') end # Logs out current logged in user session @@ -228,8 +228,8 @@ module SwaggerClient auth_names = [] - response = Swagger::Request.new(:GET, path, {:params => query_params, :headers => header_params, :form_params => form_params, :body => post_body, :auth_names => auth_names}).make.body - obj = User.new() and obj.build_from_hash(response) + response = Swagger::Request.new(:GET, path, {:params => query_params, :headers => header_params, :form_params => form_params, :body => post_body, :auth_names => auth_names}).make + response.deserialize('User') end # Updated user diff --git a/samples/client/petstore/ruby/lib/swagger_client/models/base_object.rb b/samples/client/petstore/ruby/lib/swagger_client/models/base_object.rb index 642e4769e559..a14e90350dbb 100644 --- a/samples/client/petstore/ruby/lib/swagger_client/models/base_object.rb +++ b/samples/client/petstore/ruby/lib/swagger_client/models/base_object.rb @@ -15,7 +15,7 @@ module SwaggerClient def build_from_hash(attributes) return nil unless attributes.is_a?(Hash) self.class.swagger_types.each_pair do |key, type| - if type =~ /^array\[(.*)\]/i + if type =~ /^Array<(.*)>/i if attributes[self.class.attribute_map[key]].is_a?(Array) self.send("#{key}=", attributes[self.class.attribute_map[key]].map{ |v| _deserialize($1, v) } ) else @@ -35,13 +35,13 @@ module SwaggerClient case type.to_sym when :DateTime DateTime.parse(value) - when :string + when :String value.to_s - when :int + when :Integer value.to_i - when :double + when :Float value.to_f - when :boolean + when :BOOLEAN if value =~ /^(true|t|yes|y|1)$/i true else diff --git a/samples/client/petstore/ruby/lib/swagger_client/models/category.rb b/samples/client/petstore/ruby/lib/swagger_client/models/category.rb index fe195c7ac871..d856563b11dd 100644 --- a/samples/client/petstore/ruby/lib/swagger_client/models/category.rb +++ b/samples/client/petstore/ruby/lib/swagger_client/models/category.rb @@ -18,8 +18,8 @@ module SwaggerClient # attribute type def self.swagger_types { - :'id' => :'int', - :'name' => :'string' + :'id' => :'Integer', + :'name' => :'String' } end diff --git a/samples/client/petstore/ruby/lib/swagger_client/models/order.rb b/samples/client/petstore/ruby/lib/swagger_client/models/order.rb index 3fe0282ed9b8..2cd1ff18f5d4 100644 --- a/samples/client/petstore/ruby/lib/swagger_client/models/order.rb +++ b/samples/client/petstore/ruby/lib/swagger_client/models/order.rb @@ -30,12 +30,12 @@ module SwaggerClient # attribute type def self.swagger_types { - :'id' => :'int', - :'pet_id' => :'int', - :'quantity' => :'int', + :'id' => :'Integer', + :'pet_id' => :'Integer', + :'quantity' => :'Integer', :'ship_date' => :'DateTime', - :'status' => :'string', - :'complete' => :'boolean' + :'status' => :'String', + :'complete' => :'BOOLEAN' } end diff --git a/samples/client/petstore/ruby/lib/swagger_client/models/pet.rb b/samples/client/petstore/ruby/lib/swagger_client/models/pet.rb index 32f95646c726..f1f1d1434f45 100644 --- a/samples/client/petstore/ruby/lib/swagger_client/models/pet.rb +++ b/samples/client/petstore/ruby/lib/swagger_client/models/pet.rb @@ -30,12 +30,12 @@ module SwaggerClient # attribute type def self.swagger_types { - :'id' => :'int', + :'id' => :'Integer', :'category' => :'Category', - :'name' => :'string', - :'photo_urls' => :'array[string]', - :'tags' => :'array[Tag]', - :'status' => :'string' + :'name' => :'String', + :'photo_urls' => :'Array', + :'tags' => :'Array', + :'status' => :'String' } end diff --git a/samples/client/petstore/ruby/lib/swagger_client/models/tag.rb b/samples/client/petstore/ruby/lib/swagger_client/models/tag.rb index 9c5cdde1af67..677c828aeded 100644 --- a/samples/client/petstore/ruby/lib/swagger_client/models/tag.rb +++ b/samples/client/petstore/ruby/lib/swagger_client/models/tag.rb @@ -18,8 +18,8 @@ module SwaggerClient # attribute type def self.swagger_types { - :'id' => :'int', - :'name' => :'string' + :'id' => :'Integer', + :'name' => :'String' } end diff --git a/samples/client/petstore/ruby/lib/swagger_client/models/user.rb b/samples/client/petstore/ruby/lib/swagger_client/models/user.rb index 2d723da54c44..ed7a21e167ff 100644 --- a/samples/client/petstore/ruby/lib/swagger_client/models/user.rb +++ b/samples/client/petstore/ruby/lib/swagger_client/models/user.rb @@ -36,14 +36,14 @@ module SwaggerClient # attribute type def self.swagger_types { - :'id' => :'int', - :'username' => :'string', - :'first_name' => :'string', - :'last_name' => :'string', - :'email' => :'string', - :'password' => :'string', - :'phone' => :'string', - :'user_status' => :'int' + :'id' => :'Integer', + :'username' => :'String', + :'first_name' => :'String', + :'last_name' => :'String', + :'email' => :'String', + :'password' => :'String', + :'phone' => :'String', + :'user_status' => :'Integer' } end diff --git a/samples/client/petstore/ruby/lib/swagger_client/swagger/response.rb b/samples/client/petstore/ruby/lib/swagger_client/swagger/response.rb index 538821bea691..212f1fd15ab7 100644 --- a/samples/client/petstore/ruby/lib/swagger_client/swagger/response.rb +++ b/samples/client/petstore/ruby/lib/swagger_client/swagger/response.rb @@ -2,6 +2,7 @@ module SwaggerClient module Swagger class Response require 'json' + require 'date' attr_accessor :raw @@ -9,8 +10,8 @@ module SwaggerClient self.raw = raw case self.code - when 500..510 then raise(ServerError, self.error_message) - when 299..426 then raise(ClientError, self.error_message) + when 500..510 then raise(ServerError, self.body) + when 299..426 then raise(ClientError, self.body) end end @@ -18,19 +19,58 @@ module SwaggerClient raw.code end - # Account for error messages that take different forms... - def error_message - body['message'] - rescue - body + def body + raw.body end - # If body is JSON, parse it - # Otherwise return raw string - def body - JSON.parse(raw.body, :symbolize_names => true) - rescue - raw.body + # Deserialize the raw response body to the given return type. + # + # @param [String] return_type some examples: "User", "Array[User]", "Hash[String,Integer]" + def deserialize(return_type) + return nil if body.blank? + + # ensuring a default content type + content_type = raw.headers_hash['Content-Type'] || 'application/json' + + unless content_type.start_with?('application/json') + fail "Content-Type is not supported: #{content_type}" + end + + begin + data = JSON.parse(body, :symbolize_names => true) + rescue JSON::ParserError => e + if return_type == 'String' + return body + else + raise e + end + end + + build_models data, return_type + end + + # Build model(s) from Hash data for array/hash values of the response. + def build_models(data, return_type) + case return_type + when /\AArray<(.+)>\z/ + sub_type = $1 + data.map {|item| build_models(item, sub_type) } + when /\AHash\\z/ + sub_type = $1 + {}.tap do |hash| + data.each {|k, v| hash[k] = build_models(v, sub_type) } + end + when 'String', 'Integer', 'Float', 'BOOLEAN' + # primitives, return directly + data + when 'DateTime' + DateTime.parse data + else + # models + SwaggerClient.const_get(return_type).new.tap do |model| + model.build_from_hash data + end + end end # `headers_hash` is a Typhoeus-specific extension of Hash, @@ -58,7 +98,7 @@ module SwaggerClient def pretty_body return unless body.present? case format - when 'json' then JSON.pretty_generate(body).gsub(/\n/, '
') + when 'json' then JSON.pretty_generate(JSON.parse(body)).gsub(/\n/, '
') end end From 36f0ed6d0c8fdcd3f773e01fbcca71a148a07588 Mon Sep 17 00:00:00 2001 From: xhh Date: Fri, 12 Jun 2015 22:44:52 +0800 Subject: [PATCH 3/9] Add test cases for Response#deserialize --- .../petstore/ruby/spec/response_spec.rb | 35 ++++++++++++++----- 1 file changed, 26 insertions(+), 9 deletions(-) diff --git a/samples/client/petstore/ruby/spec/response_spec.rb b/samples/client/petstore/ruby/spec/response_spec.rb index 528b67e1fa71..8d75c6d1fae5 100644 --- a/samples/client/petstore/ruby/spec/response_spec.rb +++ b/samples/client/petstore/ruby/spec/response_spec.rb @@ -8,7 +8,6 @@ describe SwaggerClient::Swagger::Response do end before(:each) do - VCR.use_cassette('pet_resource', :record => :new_episodes) do @raw = Typhoeus::Request.get("http://petstore.swagger.io/v2/pet/10002") end @@ -18,8 +17,10 @@ describe SwaggerClient::Swagger::Response do describe "initialization" do it "sets body" do - @response.body.class.should == Hash - @response.body.has_key?(:'name').should == true + @response.body.should be_a(String) + data = JSON.parse(@response.body) + data.should be_a(Hash) + data['id'].should == 10002 end it "sets code" do @@ -30,9 +31,8 @@ describe SwaggerClient::Swagger::Response do @response.headers.class.should == Hash end end - - describe "format" do + describe "format" do it "recognizes json" do @response.format.should == 'json' @response.json?.should == true @@ -47,19 +47,36 @@ describe SwaggerClient::Swagger::Response do @response.format.should == 'xml' @response.xml?.should == true end - end - + describe "prettiness" do - it "has a pretty json body" do @response.pretty_body.should =~ /\{.*\}/ end - + it "has pretty headers" do @response.pretty_headers.should =~ /\{.*\}/ end + end + describe "deserialize" do + it "handles Hash" do + @response.stub(:body) { '{"message": "Hello"}' } + data = @response.deserialize('Hash') + data.should be_a(Hash) + data.should == {:message => 'Hello'} + end + + it "handles Hash" do + json = @response.body + @response.stub(:body) { "{\"pet\": #{json}}" } + data = @response.deserialize('Hash') + data.should be_a(Hash) + data.keys.should == [:pet] + pet = data[:pet] + pet.should be_a(SwaggerClient::Pet) + pet.id.should == 10002 + end end end From 80616b4c2baac0b6a4e45b634c27e0f52bb8518f Mon Sep 17 00:00:00 2001 From: xhh Date: Fri, 12 Jun 2015 23:03:17 +0800 Subject: [PATCH 4/9] Add test cases for StoreApi#get_inventory --- samples/client/petstore/ruby/spec/pet_spec.rb | 21 +++++++++++++------ .../client/petstore/ruby/spec/store_spec.rb | 10 +++++++++ 2 files changed, 25 insertions(+), 6 deletions(-) diff --git a/samples/client/petstore/ruby/spec/pet_spec.rb b/samples/client/petstore/ruby/spec/pet_spec.rb index 68858c7b6cd9..e05dd726f135 100644 --- a/samples/client/petstore/ruby/spec/pet_spec.rb +++ b/samples/client/petstore/ruby/spec/pet_spec.rb @@ -13,9 +13,14 @@ describe "Pet" do tag2 = SwaggerClient::Tag.new({'id' => 2, 'name'=> 'tag2'}) category1 = SwaggerClient::Category.new({:id => 1, :name => 'category unknown'}) # initalize using both string and symbol key - pet_hash = {:'id' => 10002, :'name' => "RUBY UNIT TESTING", :'status' => "pending", - :'photo_urls' => ["url1", "url2"], :'category' => category1, - :'tags' => [tag1, tag2]} + pet_hash = { + :id => 10002, + :name => "RUBY UNIT TESTING", + :status => "pending", + :photo_urls => ["url1", "url2"], + :category => category1, + :tags => [tag1, tag2] + } pet = SwaggerClient::Pet.new(pet_hash) # test new pet.name.should == "RUBY UNIT TESTING" @@ -48,6 +53,10 @@ describe "Pet" do it "should find pets by status" do pets = SwaggerClient::PetApi.find_pets_by_status(:status => 'available') pets.length.should >= 3 + pets.each do |pet| + pet.should be_a(SwaggerClient::Pet) + pet.status.should == 'available' + end end it "should not find a pet with invalid status" do @@ -57,11 +66,11 @@ describe "Pet" do it "should find a pet by status" do pets = SwaggerClient::PetApi.find_pets_by_status(:status => "available,sold") - pets.map {|pet| - if(pet.status != 'available' && pet.status != 'sold') + pets.each do |pet| + if pet.status != 'available' && pet.status != 'sold' raise "pet status wasn't right" end - } + end end it "should update a pet" do diff --git a/samples/client/petstore/ruby/spec/store_spec.rb b/samples/client/petstore/ruby/spec/store_spec.rb index 1b37400bc5c3..3ad09f1ad617 100644 --- a/samples/client/petstore/ruby/spec/store_spec.rb +++ b/samples/client/petstore/ruby/spec/store_spec.rb @@ -10,4 +10,14 @@ describe "Store" do item = SwaggerClient::StoreApi.get_order_by_id(10002) item.id.should == 10002 end + + it "should featch the inventory" do + result = SwaggerClient::StoreApi.get_inventory + result.should be_a(Hash) + result.should_not be_empty + result.each do |k, v| + k.should be_a(Symbol) + v.should be_a(Integer) + end + end end From e9c1dd78428714bb94f907a7485501aaaa5bd57c Mon Sep 17 00:00:00 2001 From: xhh Date: Mon, 15 Jun 2015 12:49:17 +0800 Subject: [PATCH 5/9] Regard bare "object" type as Object, add comments The handling of base "object" type (without definions of "additionalProperties") is similar to Java generator now. --- .../codegen/languages/RubyClientCodegen.java | 2 +- .../resources/ruby/swagger/response.mustache | 27 ++++++++++++------- .../lib/swagger_client/swagger/response.rb | 27 ++++++++++++------- 3 files changed, 35 insertions(+), 21 deletions(-) diff --git a/modules/swagger-codegen/src/main/java/io/swagger/codegen/languages/RubyClientCodegen.java b/modules/swagger-codegen/src/main/java/io/swagger/codegen/languages/RubyClientCodegen.java index 2ee227fea29c..46c0f70a4b6d 100644 --- a/modules/swagger-codegen/src/main/java/io/swagger/codegen/languages/RubyClientCodegen.java +++ b/modules/swagger-codegen/src/main/java/io/swagger/codegen/languages/RubyClientCodegen.java @@ -62,7 +62,7 @@ public class RubyClientCodegen extends DefaultCodegen implements CodegenConfig { typeMapping.put("array", "Array"); typeMapping.put("List", "Array"); typeMapping.put("map", "Hash"); - typeMapping.put("object", "Hash"); + typeMapping.put("object", "Object"); String baseFolder = "lib" + File.separatorChar + gemName; String swaggerFolder = baseFolder + File.separatorChar + "swagger"; diff --git a/modules/swagger-codegen/src/main/resources/ruby/swagger/response.mustache b/modules/swagger-codegen/src/main/resources/ruby/swagger/response.mustache index 3abc7df40d7a..717ce49c3d5f 100644 --- a/modules/swagger-codegen/src/main/resources/ruby/swagger/response.mustache +++ b/modules/swagger-codegen/src/main/resources/ruby/swagger/response.mustache @@ -49,24 +49,31 @@ module {{moduleName}} build_models data, return_type end - # Build model(s) from Hash data for array/hash values of the response. + # Walk through the given data and, when necessary, build model(s) from + # Hash data for array/hash values of the response. def build_models(data, return_type) case return_type - when /\AArray<(.+)>\z/ - sub_type = $1 - data.map {|item| build_models(item, sub_type) } - when /\AHash\\z/ - sub_type = $1 - {}.tap do |hash| - data.each {|k, v| hash[k] = build_models(v, sub_type) } - end when 'String', 'Integer', 'Float', 'BOOLEAN' # primitives, return directly data when 'DateTime' + # parse date time (expecting ISO 8601 format) DateTime.parse data + when 'Object' + # generic object, return directly + data + when /\AArray<(.+)>\z/ + # e.g. Array + sub_type = $1 + data.map {|item| build_models(item, sub_type) } + when /\AHash\\z/ + # e.g. Hash + sub_type = $1 + {}.tap do |hash| + data.each {|k, v| hash[k] = build_models(v, sub_type) } + end else - # models + # models, e.g. Pet {{moduleName}}.const_get(return_type).new.tap do |model| model.build_from_hash data end diff --git a/samples/client/petstore/ruby/lib/swagger_client/swagger/response.rb b/samples/client/petstore/ruby/lib/swagger_client/swagger/response.rb index 212f1fd15ab7..53b60205a759 100644 --- a/samples/client/petstore/ruby/lib/swagger_client/swagger/response.rb +++ b/samples/client/petstore/ruby/lib/swagger_client/swagger/response.rb @@ -49,24 +49,31 @@ module SwaggerClient build_models data, return_type end - # Build model(s) from Hash data for array/hash values of the response. + # Walk through the given data and, when necessary, build model(s) from + # Hash data for array/hash values of the response. def build_models(data, return_type) case return_type - when /\AArray<(.+)>\z/ - sub_type = $1 - data.map {|item| build_models(item, sub_type) } - when /\AHash\\z/ - sub_type = $1 - {}.tap do |hash| - data.each {|k, v| hash[k] = build_models(v, sub_type) } - end when 'String', 'Integer', 'Float', 'BOOLEAN' # primitives, return directly data when 'DateTime' + # parse date time (expecting ISO 8601 format) DateTime.parse data + when 'Object' + # generic object, return directly + data + when /\AArray<(.+)>\z/ + # e.g. Array + sub_type = $1 + data.map {|item| build_models(item, sub_type) } + when /\AHash\\z/ + # e.g. Hash + sub_type = $1 + {}.tap do |hash| + data.each {|k, v| hash[k] = build_models(v, sub_type) } + end else - # models + # models, e.g. Pet SwaggerClient.const_get(return_type).new.tap do |model| model.build_from_hash data end From 9d5928551bdcf49c62215a4285a0d1ce6553ff8f Mon Sep 17 00:00:00 2001 From: xhh Date: Mon, 15 Jun 2015 16:38:08 +0800 Subject: [PATCH 6/9] Unify ClientError and ServerError into ApiError in Ruby generator --- .../codegen/languages/RubyClientCodegen.java | 1 + .../src/main/resources/ruby/swagger.mustache | 8 +----- .../resources/ruby/swagger/api_error.mustache | 26 +++++++++++++++++++ .../resources/ruby/swagger/response.mustache | 8 +++--- .../resources/ruby/swagger_client.mustache | 1 + .../petstore/ruby/lib/swagger_client.rb | 1 + .../ruby/lib/swagger_client/swagger.rb | 8 +----- .../lib/swagger_client/swagger/api_error.rb | 26 +++++++++++++++++++ .../lib/swagger_client/swagger/response.rb | 8 +++--- 9 files changed, 67 insertions(+), 20 deletions(-) create mode 100644 modules/swagger-codegen/src/main/resources/ruby/swagger/api_error.mustache create mode 100644 samples/client/petstore/ruby/lib/swagger_client/swagger/api_error.rb diff --git a/modules/swagger-codegen/src/main/java/io/swagger/codegen/languages/RubyClientCodegen.java b/modules/swagger-codegen/src/main/java/io/swagger/codegen/languages/RubyClientCodegen.java index 46c0f70a4b6d..41d9f494a7c3 100644 --- a/modules/swagger-codegen/src/main/java/io/swagger/codegen/languages/RubyClientCodegen.java +++ b/modules/swagger-codegen/src/main/java/io/swagger/codegen/languages/RubyClientCodegen.java @@ -73,6 +73,7 @@ public class RubyClientCodegen extends DefaultCodegen implements CodegenConfig { supportingFiles.add(new SupportingFile("swagger.mustache", baseFolder, "swagger.rb")); supportingFiles.add(new SupportingFile("swagger" + File.separatorChar + "request.mustache", swaggerFolder, "request.rb")); supportingFiles.add(new SupportingFile("swagger" + File.separatorChar + "response.mustache", swaggerFolder, "response.rb")); + supportingFiles.add(new SupportingFile("swagger" + File.separatorChar + "api_error.mustache", swaggerFolder, "api_error.rb")); supportingFiles.add(new SupportingFile("swagger" + File.separatorChar + "version.mustache", swaggerFolder, "version.rb")); supportingFiles.add(new SupportingFile("swagger" + File.separatorChar + "configuration.mustache", swaggerFolder, "configuration.rb")); supportingFiles.add(new SupportingFile("base_object.mustache", modelFolder, "base_object.rb")); diff --git a/modules/swagger-codegen/src/main/resources/ruby/swagger.mustache b/modules/swagger-codegen/src/main/resources/ruby/swagger.mustache index dd2f630a8c95..239e3cfac268 100644 --- a/modules/swagger-codegen/src/main/resources/ruby/swagger.mustache +++ b/modules/swagger-codegen/src/main/resources/ruby/swagger.mustache @@ -52,7 +52,7 @@ module {{moduleName}} return if Swagger.authenticated? if Swagger.configuration.username.blank? || Swagger.configuration.password.blank? - raise ClientError, "Username and password are required to authenticate." + raise ApiError, "Username and password are required to authenticate." end request = Swagger::Request.new( @@ -69,10 +69,4 @@ module {{moduleName}} end end end - - class ServerError < StandardError - end - - class ClientError < StandardError - end end diff --git a/modules/swagger-codegen/src/main/resources/ruby/swagger/api_error.mustache b/modules/swagger-codegen/src/main/resources/ruby/swagger/api_error.mustache new file mode 100644 index 000000000000..552161238a0c --- /dev/null +++ b/modules/swagger-codegen/src/main/resources/ruby/swagger/api_error.mustache @@ -0,0 +1,26 @@ +module {{moduleName}} + module Swagger + class ApiError < StandardError + attr_reader :code, :response_headers, :response_body + + # Usage examples: + # ApiError.new + # ApiError.new("message") + # ApiError.new(:code => 500, :response_headers => {}, :response_body => "") + # ApiError.new(:code => 404, :message => "Not Found") + def initialize(arg = nil) + if arg.is_a? Hash + arg.each do |k, v| + if k.to_s == 'message' + super v + else + instance_variable_set "@#{k}", v + end + end + else + super arg + end + end + end + end +end diff --git a/modules/swagger-codegen/src/main/resources/ruby/swagger/response.mustache b/modules/swagger-codegen/src/main/resources/ruby/swagger/response.mustache index 717ce49c3d5f..b621110935a9 100644 --- a/modules/swagger-codegen/src/main/resources/ruby/swagger/response.mustache +++ b/modules/swagger-codegen/src/main/resources/ruby/swagger/response.mustache @@ -9,9 +9,11 @@ module {{moduleName}} def initialize(raw) self.raw = raw - case self.code - when 500..510 then raise(ServerError, self.body) - when 299..426 then raise(ClientError, self.body) + unless raw.success? + fail ApiError.new(:code => code, + :response_headers => headers, + :response_body => body), + raw.status_message end end diff --git a/modules/swagger-codegen/src/main/resources/ruby/swagger_client.mustache b/modules/swagger-codegen/src/main/resources/ruby/swagger_client.mustache index df675ddf26ea..69454179283e 100644 --- a/modules/swagger-codegen/src/main/resources/ruby/swagger_client.mustache +++ b/modules/swagger-codegen/src/main/resources/ruby/swagger_client.mustache @@ -2,6 +2,7 @@ require '{{gemName}}/monkey' require '{{gemName}}/swagger' require '{{gemName}}/swagger/configuration' +require '{{gemName}}/swagger/api_error' require '{{gemName}}/swagger/request' require '{{gemName}}/swagger/response' require '{{gemName}}/swagger/version' diff --git a/samples/client/petstore/ruby/lib/swagger_client.rb b/samples/client/petstore/ruby/lib/swagger_client.rb index 6d239185005c..42380927f824 100644 --- a/samples/client/petstore/ruby/lib/swagger_client.rb +++ b/samples/client/petstore/ruby/lib/swagger_client.rb @@ -2,6 +2,7 @@ require 'swagger_client/monkey' require 'swagger_client/swagger' require 'swagger_client/swagger/configuration' +require 'swagger_client/swagger/api_error' require 'swagger_client/swagger/request' require 'swagger_client/swagger/response' require 'swagger_client/swagger/version' diff --git a/samples/client/petstore/ruby/lib/swagger_client/swagger.rb b/samples/client/petstore/ruby/lib/swagger_client/swagger.rb index 2e2632c169df..477ec89ba819 100644 --- a/samples/client/petstore/ruby/lib/swagger_client/swagger.rb +++ b/samples/client/petstore/ruby/lib/swagger_client/swagger.rb @@ -52,7 +52,7 @@ module SwaggerClient return if Swagger.authenticated? if Swagger.configuration.username.blank? || Swagger.configuration.password.blank? - raise ClientError, "Username and password are required to authenticate." + raise ApiError, "Username and password are required to authenticate." end request = Swagger::Request.new( @@ -69,10 +69,4 @@ module SwaggerClient end end end - - class ServerError < StandardError - end - - class ClientError < StandardError - end end diff --git a/samples/client/petstore/ruby/lib/swagger_client/swagger/api_error.rb b/samples/client/petstore/ruby/lib/swagger_client/swagger/api_error.rb new file mode 100644 index 000000000000..12319927acec --- /dev/null +++ b/samples/client/petstore/ruby/lib/swagger_client/swagger/api_error.rb @@ -0,0 +1,26 @@ +module SwaggerClient + module Swagger + class ApiError < StandardError + attr_reader :code, :response_headers, :response_body + + # Usage examples: + # ApiError.new + # ApiError.new("message") + # ApiError.new(:code => 500, :response_headers => {}, :response_body => "") + # ApiError.new(:code => 404, :message => "Not Found") + def initialize(arg = nil) + if arg.is_a? Hash + arg.each do |k, v| + if k.to_s == 'message' + super v + else + instance_variable_set "@#{k}", v + end + end + else + super arg + end + end + end + end +end diff --git a/samples/client/petstore/ruby/lib/swagger_client/swagger/response.rb b/samples/client/petstore/ruby/lib/swagger_client/swagger/response.rb index 53b60205a759..f560006de6d7 100644 --- a/samples/client/petstore/ruby/lib/swagger_client/swagger/response.rb +++ b/samples/client/petstore/ruby/lib/swagger_client/swagger/response.rb @@ -9,9 +9,11 @@ module SwaggerClient def initialize(raw) self.raw = raw - case self.code - when 500..510 then raise(ServerError, self.body) - when 299..426 then raise(ClientError, self.body) + unless raw.success? + fail ApiError.new(:code => code, + :response_headers => headers, + :response_body => body), + raw.status_message end end From ec8e5179cbc487f3895ac6e79738cb707a779503 Mon Sep 17 00:00:00 2001 From: xhh Date: Mon, 15 Jun 2015 16:46:30 +0800 Subject: [PATCH 7/9] Remove unused comments --- .../src/main/resources/ruby/monkey.mustache | 152 +++++++++--------- .../ruby/lib/swagger_client/monkey.rb | 152 +++++++++--------- 2 files changed, 144 insertions(+), 160 deletions(-) diff --git a/modules/swagger-codegen/src/main/resources/ruby/monkey.mustache b/modules/swagger-codegen/src/main/resources/ruby/monkey.mustache index 28932890af95..0751d42ce63d 100644 --- a/modules/swagger-codegen/src/main/resources/ruby/monkey.mustache +++ b/modules/swagger-codegen/src/main/resources/ruby/monkey.mustache @@ -1,90 +1,82 @@ -# module Swagger - class Object - - unless Object.method_defined? :blank? - def blank? - respond_to?(:empty?) ? empty? : !self - end +class Object + unless Object.method_defined? :blank? + def blank? + respond_to?(:empty?) ? empty? : !self end - - unless Object.method_defined? :present? - def present? - !blank? - end - end - end - class String - - unless String.method_defined? :underscore - def underscore - self.gsub(/::/, '/'). - gsub(/([A-Z]+)([A-Z][a-z])/,'\1_\2'). - gsub(/([a-z\d])([A-Z])/,'\1_\2'). - tr("-", "_"). - downcase - end - end - - unless String.method_defined? :camelize - def camelize(first_letter_in_uppercase = true) - if first_letter_in_uppercase != :lower - self.to_s.gsub(/\/(.?)/) { "::#{$1.upcase}" }.gsub(/(?:^|_)(.)/) { $1.upcase } - else - self.to_s[0].chr.downcase + camelize(self)[1..-1] - end - end + unless Object.method_defined? :present? + def present? + !blank? end + end +end +class String + unless String.method_defined? :underscore + def underscore + self.gsub(/::/, '/'). + gsub(/([A-Z]+)([A-Z][a-z])/,'\1_\2'). + gsub(/([a-z\d])([A-Z])/,'\1_\2'). + tr("-", "_"). + downcase + end end - class Hash - - unless Hash.method_defined? :stringify_keys - def stringify_keys - inject({}) do |options, (key, value)| - options[key.to_s] = value - options - end + unless String.method_defined? :camelize + def camelize(first_letter_in_uppercase = true) + if first_letter_in_uppercase != :lower + self.to_s.gsub(/\/(.?)/) { "::#{$1.upcase}" }.gsub(/(?:^|_)(.)/) { $1.upcase } + else + self.to_s[0].chr.downcase + camelize(self)[1..-1] end end - - unless Hash.method_defined? :stringify_keys! - def stringify_keys! - self.replace(self.stringify_keys) - end - end - - unless Hash.method_defined? :symbolize_keys - def symbolize_keys - inject({}) do |options, (key, value)| - options[(key.to_sym rescue key) || key] = value - options - end - end - end - - unless Hash.method_defined? :symbolize_keys! - def symbolize_keys! - self.replace(self.symbolize_keys) - end - end - - unless Hash.method_defined? :symbolize_and_underscore_keys - def symbolize_and_underscore_keys - inject({}) do |options, (key, value)| - options[(key.to_s.underscore.to_sym rescue key) || key] = value - options - end - end - end - - unless Hash.method_defined? :symbolize_and_underscore_keys! - def symbolize_and_underscore_keys! - self.replace(self.symbolize_and_underscore_keys) - end - end - end -# end \ No newline at end of file +end + +class Hash + unless Hash.method_defined? :stringify_keys + def stringify_keys + inject({}) do |options, (key, value)| + options[key.to_s] = value + options + end + end + end + + unless Hash.method_defined? :stringify_keys! + def stringify_keys! + self.replace(self.stringify_keys) + end + end + + unless Hash.method_defined? :symbolize_keys + def symbolize_keys + inject({}) do |options, (key, value)| + options[(key.to_sym rescue key) || key] = value + options + end + end + end + + unless Hash.method_defined? :symbolize_keys! + def symbolize_keys! + self.replace(self.symbolize_keys) + end + end + + unless Hash.method_defined? :symbolize_and_underscore_keys + def symbolize_and_underscore_keys + inject({}) do |options, (key, value)| + options[(key.to_s.underscore.to_sym rescue key) || key] = value + options + end + end + end + + unless Hash.method_defined? :symbolize_and_underscore_keys! + def symbolize_and_underscore_keys! + self.replace(self.symbolize_and_underscore_keys) + end + end +end diff --git a/samples/client/petstore/ruby/lib/swagger_client/monkey.rb b/samples/client/petstore/ruby/lib/swagger_client/monkey.rb index 28932890af95..0751d42ce63d 100644 --- a/samples/client/petstore/ruby/lib/swagger_client/monkey.rb +++ b/samples/client/petstore/ruby/lib/swagger_client/monkey.rb @@ -1,90 +1,82 @@ -# module Swagger - class Object - - unless Object.method_defined? :blank? - def blank? - respond_to?(:empty?) ? empty? : !self - end +class Object + unless Object.method_defined? :blank? + def blank? + respond_to?(:empty?) ? empty? : !self end - - unless Object.method_defined? :present? - def present? - !blank? - end - end - end - class String - - unless String.method_defined? :underscore - def underscore - self.gsub(/::/, '/'). - gsub(/([A-Z]+)([A-Z][a-z])/,'\1_\2'). - gsub(/([a-z\d])([A-Z])/,'\1_\2'). - tr("-", "_"). - downcase - end - end - - unless String.method_defined? :camelize - def camelize(first_letter_in_uppercase = true) - if first_letter_in_uppercase != :lower - self.to_s.gsub(/\/(.?)/) { "::#{$1.upcase}" }.gsub(/(?:^|_)(.)/) { $1.upcase } - else - self.to_s[0].chr.downcase + camelize(self)[1..-1] - end - end + unless Object.method_defined? :present? + def present? + !blank? end + end +end +class String + unless String.method_defined? :underscore + def underscore + self.gsub(/::/, '/'). + gsub(/([A-Z]+)([A-Z][a-z])/,'\1_\2'). + gsub(/([a-z\d])([A-Z])/,'\1_\2'). + tr("-", "_"). + downcase + end end - class Hash - - unless Hash.method_defined? :stringify_keys - def stringify_keys - inject({}) do |options, (key, value)| - options[key.to_s] = value - options - end + unless String.method_defined? :camelize + def camelize(first_letter_in_uppercase = true) + if first_letter_in_uppercase != :lower + self.to_s.gsub(/\/(.?)/) { "::#{$1.upcase}" }.gsub(/(?:^|_)(.)/) { $1.upcase } + else + self.to_s[0].chr.downcase + camelize(self)[1..-1] end end - - unless Hash.method_defined? :stringify_keys! - def stringify_keys! - self.replace(self.stringify_keys) - end - end - - unless Hash.method_defined? :symbolize_keys - def symbolize_keys - inject({}) do |options, (key, value)| - options[(key.to_sym rescue key) || key] = value - options - end - end - end - - unless Hash.method_defined? :symbolize_keys! - def symbolize_keys! - self.replace(self.symbolize_keys) - end - end - - unless Hash.method_defined? :symbolize_and_underscore_keys - def symbolize_and_underscore_keys - inject({}) do |options, (key, value)| - options[(key.to_s.underscore.to_sym rescue key) || key] = value - options - end - end - end - - unless Hash.method_defined? :symbolize_and_underscore_keys! - def symbolize_and_underscore_keys! - self.replace(self.symbolize_and_underscore_keys) - end - end - end -# end \ No newline at end of file +end + +class Hash + unless Hash.method_defined? :stringify_keys + def stringify_keys + inject({}) do |options, (key, value)| + options[key.to_s] = value + options + end + end + end + + unless Hash.method_defined? :stringify_keys! + def stringify_keys! + self.replace(self.stringify_keys) + end + end + + unless Hash.method_defined? :symbolize_keys + def symbolize_keys + inject({}) do |options, (key, value)| + options[(key.to_sym rescue key) || key] = value + options + end + end + end + + unless Hash.method_defined? :symbolize_keys! + def symbolize_keys! + self.replace(self.symbolize_keys) + end + end + + unless Hash.method_defined? :symbolize_and_underscore_keys + def symbolize_and_underscore_keys + inject({}) do |options, (key, value)| + options[(key.to_s.underscore.to_sym rescue key) || key] = value + options + end + end + end + + unless Hash.method_defined? :symbolize_and_underscore_keys! + def symbolize_and_underscore_keys! + self.replace(self.symbolize_and_underscore_keys) + end + end +end From a59d4ba346ebf40e46f0661e5a091e231d35ef05 Mon Sep 17 00:00:00 2001 From: xhh Date: Mon, 15 Jun 2015 16:51:38 +0800 Subject: [PATCH 8/9] Add test case for finding nonexistent pet --- samples/client/petstore/ruby/spec/pet_spec.rb | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/samples/client/petstore/ruby/spec/pet_spec.rb b/samples/client/petstore/ruby/spec/pet_spec.rb index e05dd726f135..52030b7bf51d 100644 --- a/samples/client/petstore/ruby/spec/pet_spec.rb +++ b/samples/client/petstore/ruby/spec/pet_spec.rb @@ -50,6 +50,19 @@ describe "Pet" do pet.category.name.should == "category test" end + it "should not find a pet that does not exist" do + begin + SwaggerClient::PetApi.get_pet_by_id(-1) + fail 'it should raise error' + rescue SwaggerClient::Swagger::ApiError => e + e.code.should == 404 + e.message.should == 'Not Found' + e.response_body.should == '{"code":1,"type":"error","message":"Pet not found"}' + e.response_headers.should be_a(Hash) + e.response_headers['Content-Type'].should == 'application/json' + end + end + it "should find pets by status" do pets = SwaggerClient::PetApi.find_pets_by_status(:status => 'available') pets.length.should >= 3 From 7c355030f47c827a6231d4dc1173fb7a452a283e Mon Sep 17 00:00:00 2001 From: xhh Date: Tue, 16 Jun 2015 18:41:51 +0800 Subject: [PATCH 9/9] Add to_s method for models --- .../main/resources/ruby/base_object.mustache | 20 +++++++++---------- .../lib/swagger_client/models/base_object.rb | 20 +++++++++---------- 2 files changed, 20 insertions(+), 20 deletions(-) diff --git a/modules/swagger-codegen/src/main/resources/ruby/base_object.mustache b/modules/swagger-codegen/src/main/resources/ruby/base_object.mustache index 2f1e1064a5be..eda92028f789 100644 --- a/modules/swagger-codegen/src/main/resources/ruby/base_object.mustache +++ b/modules/swagger-codegen/src/main/resources/ruby/base_object.mustache @@ -2,15 +2,6 @@ module {{moduleName}} # base class containing fundamental method such as to_hash, build_from_hash and more class BaseObject - # return the object in the form of hash - def to_body - body = {} - self.class.attribute_map.each_pair do |key, value| - body[value] = self.send(key) unless self.send(key).nil? - end - body - end - # build the object from hash def build_from_hash(attributes) return nil unless attributes.is_a?(Hash) @@ -53,7 +44,16 @@ module {{moduleName}} end end - # to_body is an alias to to_body (backward compatibility) + def to_s + to_hash.to_s + end + + # to_body is an alias to to_body (backward compatibility)) + def to_body + to_hash + end + + # return the object in the form of hash def to_hash hash = {} self.class.attribute_map.each_pair do |key, value| diff --git a/samples/client/petstore/ruby/lib/swagger_client/models/base_object.rb b/samples/client/petstore/ruby/lib/swagger_client/models/base_object.rb index a14e90350dbb..b0fa43c83595 100644 --- a/samples/client/petstore/ruby/lib/swagger_client/models/base_object.rb +++ b/samples/client/petstore/ruby/lib/swagger_client/models/base_object.rb @@ -2,15 +2,6 @@ module SwaggerClient # base class containing fundamental method such as to_hash, build_from_hash and more class BaseObject - # return the object in the form of hash - def to_body - body = {} - self.class.attribute_map.each_pair do |key, value| - body[value] = self.send(key) unless self.send(key).nil? - end - body - end - # build the object from hash def build_from_hash(attributes) return nil unless attributes.is_a?(Hash) @@ -53,7 +44,16 @@ module SwaggerClient end end - # to_body is an alias to to_body (backward compatibility) + def to_s + to_hash.to_s + end + + # to_body is an alias to to_body (backward compatibility)) + def to_body + to_hash + end + + # return the object in the form of hash def to_hash hash = {} self.class.attribute_map.each_pair do |key, value|