Skip to content

Commit

Permalink
fix(ruby): correct oneOf deserialization (#2559)
Browse files Browse the repository at this point in the history
  • Loading branch information
millotp authored Jan 17, 2024
1 parent 06a4c12 commit 6c099d4
Show file tree
Hide file tree
Showing 10 changed files with 28 additions and 15 deletions.
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
require 'cgi'
require 'json'

module Algolia
class ApiClient
Expand Down
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@
"docker:setup": "./scripts/docker/setup.sh",
"fix:json": "eslint --ext=json . --fix",
"github-actions:lint": "eslint --ext=yml .github/",
"postinstall": "husky install && yarn workspace eslint-plugin-automation-custom build && yarn workspace scripts tsc",
"postinstall": "husky install && yarn workspace eslint-plugin-automation-custom build && yarn workspace scripts build:cli",
"playground:browser": "yarn workspace javascript-browser-playground start",
"release": "yarn workspace scripts createReleasePR",
"scripts:build": "yarn workspace scripts build",
Expand Down
2 changes: 1 addition & 1 deletion playground/ruby/Gemfile.lock
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
PATH
remote: ../../clients/algoliasearch-client-ruby
specs:
algolia (3.0.0.alpha.1)
algolia (3.0.0.alpha.5)
faraday (>= 1.0.1, < 3.0)
faraday-net_http_persistent (>= 0.15, < 3)
net-http-persistent
Expand Down
2 changes: 1 addition & 1 deletion playground/ruby/search.rb
Original file line number Diff line number Diff line change
Expand Up @@ -4,5 +4,5 @@
Dotenv.load('../.env')

client = Algolia::SearchClient.create(ENV['ALGOLIA_APPLICATION_ID'], ENV['ALGOLIA_ADMIN_KEY'])
res = client.search_single_index('actors', Algolia::Search::SearchParamsObject.new(query: 'john'))
res = client.search_single_index('contacts', Algolia::Search::SearchParamsObject.new(query: 'Jimmie'))
puts res
4 changes: 2 additions & 2 deletions templates/ruby/api.mustache
Original file line number Diff line number Diff line change
Expand Up @@ -172,7 +172,7 @@ module {{moduleName}}
:header_params => header_params,
:query_params => query_params,
:body => post_body,
:use_read_transporter => {{#useReadTransporter}}true{{/useReadTransporter}}{{^useReadTransporter}}false{{/useReadTransporter}}
:use_read_transporter => {{#vendorExtensions.x-use-read-transporter}}true{{/vendorExtensions.x-use-read-transporter}}{{^vendorExtensions.x-use-read-transporter}}false{{/vendorExtensions.x-use-read-transporter}}
)

@api_client.call_api(:{{httpMethod}}, path, new_options)
Expand All @@ -196,7 +196,7 @@ module {{moduleName}}
# @return [{{{returnType}}}{{^returnType}}nil{{/returnType}}]
def {{operationId}}({{#allParams}}{{#required}}{{paramName}}, {{/required}}{{^required}}{{paramName}}=nil, {{/required}}{{/allParams}}request_options = {})
{{#returnType}}response = {{/returnType}}{{operationId}}_with_http_info({{#allParams}}{{paramName}}, {{/allParams}}request_options)
{{#returnType}}deserialize(response.body, request_options[:debug_return_type]{{#vendorExtensions}}{{#returnProperty}} || '{{#isArray}}Array<{{{modelModule}}}::{{complexType}}>{{/isArray}}{{^isArray}}{{^x-is-custom-request}}{{{modelModule}}}::{{/x-is-custom-request}}{{{dataType}}}{{/isArray}}'{{/returnProperty}}{{/vendorExtensions}}){{/returnType}}{{^returnType}}nil{{/returnType}}
{{#returnType}}@api_client.deserialize(response.body, request_options[:debug_return_type]{{#vendorExtensions}}{{#returnProperty}} || '{{#isArray}}Array<{{{modelModule}}}::{{complexType}}>{{/isArray}}{{^isArray}}{{^x-is-custom-request}}{{{modelModule}}}::{{/x-is-custom-request}}{{{dataType}}}{{/isArray}}'{{/returnProperty}}{{/vendorExtensions}}){{/returnType}}{{^returnType}}nil{{/returnType}}
end
{{^-last}}

Expand Down
15 changes: 11 additions & 4 deletions templates/ruby/base_object.mustache
Original file line number Diff line number Diff line change
Expand Up @@ -10,20 +10,23 @@
transformed_hash = {}
types_mapping.each_pair do |key, type|
if attributes.key?(attribute_map[key]) && attributes[attribute_map[key]].nil?
transformed_hash[key.to_s] = nil
transformed_hash[key.to_sym] = nil
elsif type =~ /\AArray<(.*)>/i
# check to ensure the input is an array given that the attribute
# is documented as an array but the input is not
if attributes[attribute_map[key]].is_a?(Array)
transformed_hash[key.to_s] = attributes[attribute_map[key]].map { |v| _deserialize(::Regexp.last_match(1), v) }
transformed_hash[key.to_sym] = attributes[attribute_map[key]].map { |v| _deserialize(::Regexp.last_match(1), v) }
end
elsif !attributes[attribute_map[key]].nil?
transformed_hash[key.to_s] = _deserialize(type, attributes[attribute_map[key]])
transformed_hash[key.to_sym] = _deserialize(type, attributes[attribute_map[key]])
end
end
{{#getAdditionalPropertiesIsAnyType}}

transformed_hash.merge!(attributes.reject { |k, _| attribute_map.key?(k.to_sym) })
# merge additional_properties into transformed_hash
@additional_properties.each_pair do |k, v|
transformed_hash[k.to_sym] = v
end unless @additional_properties.nil?
{{/getAdditionalPropertiesIsAnyType}}
new(transformed_hash)
end
Expand Down Expand Up @@ -83,6 +86,10 @@
to_hash
end

def to_json(*_args)
to_hash.to_json
end

# Returns the object in the form of hash
# @return [Hash] Returns the object in the form of hash
def to_hash
Expand Down
2 changes: 1 addition & 1 deletion templates/ruby/partial_anyof_module.mustache
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,7 @@
return data.each_with_object({}) { |(k, v), hsh| hsh[k] = find_and_cast_into_type(sub_type, v) }
end
else # model
const = {{moduleName}}.const_get(klass)
const = {{moduleName}}::{{modelModule}}.const_get(klass)
if const
if const.respond_to?(:openapi_any_of) # nested anyOf model
model = const.build(data)
Expand Down
6 changes: 3 additions & 3 deletions templates/ruby/partial_oneof_module.mustache
Original file line number Diff line number Diff line change
Expand Up @@ -51,11 +51,11 @@
klass = openapi_discriminator_mapping[discriminator_value.to_s.to_sym]
return nil unless klass

{{moduleName}}.const_get(klass).build_from_hash(data)
{{moduleName}}::{{modelModule}}.const_get(klass).build_from_hash(data)
{{/-first}}
{{/mappedModels}}
{{^mappedModels}}
{{moduleName}}.const_get(discriminator_value).build_from_hash(data)
{{moduleName}}::{{modelModule}}.const_get(discriminator_value).build_from_hash(data)
{{/mappedModels}}
{{/discriminator}}
{{^discriminator}}
Expand Down Expand Up @@ -114,7 +114,7 @@
return data.each_with_object({}) { |(k, v), hsh| hsh[k] = find_and_cast_into_type(sub_type, v) }
end
else # model
const = {{moduleName}}.const_get(klass)
const = {{moduleName}}::{{modelModule}}.const_get(klass)
if const
if const.respond_to?(:openapi_one_of) # nested oneOf model
model = const.build(data)
Expand Down
5 changes: 3 additions & 2 deletions templates/ruby/tests/requests/requests.mustache
Original file line number Diff line number Diff line change
Expand Up @@ -50,12 +50,13 @@ class Test{{#lambda.pascalcase}}{{{client}}}{{/lambda.pascalcase}} < Test::Unit:
assert_equal(res.status, {{statusCode}})
{{/statusCode}}
{{#body}}
res = @e2e_client.{{#lambda.snakecase}}{{method}}{{/lambda.snakecase}}({{#parametersWithDataType}}{{> tests/requests/generateParams}}{{/parametersWithDataType}}{{#hasRequestOptions}}{ {{#requestOptions.headers.parameters}}:header_params => JSON.parse('{{{.}}}', :symbolize_names => true),{{/requestOptions.headers.parameters}}{{#requestOptions.queryParameters.parameters}}:query_params => JSON.parse('{{{.}}}', :symbolize_names => true){{/requestOptions.queryParameters.parameters}} }{{/hasRequestOptions}})
expected_body = JSON.parse(%q({{{.}}}))
assert_equal(expected_body, union(expected_body, JSON.parse(res.body)))
assert_equal(expected_body, union(expected_body, JSON.parse(res.to_json)))
{{/body}}
{{/response}}
end

{{/tests}}
{{/blocksRequests}}
end
end
4 changes: 4 additions & 0 deletions tests/output/ruby/test/helpers.rb
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,10 @@ def union(expected, received)
return expected
end

if received.nil?
return nil
end

expected.each do |key, value|
if received.key?(key)
if value.is_a?(Array)
Expand Down

0 comments on commit 6c099d4

Please sign in to comment.