From b2252c1db43aa2ea5289b977beb9565dfad59db8 Mon Sep 17 00:00:00 2001 From: MaryamAdnan3 Date: Tue, 5 Nov 2024 11:01:23 +0500 Subject: [PATCH 1/8] feat(ruby): add support of additional properties closes #47 --- apimatic_core.gemspec | 2 +- lib/apimatic-core/utilities/api_helper.rb | 18 +++++++++++ .../utilities/api_helper_test.rb | 30 +++++++++++++++++++ 3 files changed, 49 insertions(+), 1 deletion(-) diff --git a/apimatic_core.gemspec b/apimatic_core.gemspec index c22a193..9c5c162 100644 --- a/apimatic_core.gemspec +++ b/apimatic_core.gemspec @@ -1,6 +1,6 @@ Gem::Specification.new do |s| s.name = 'apimatic_core' - s.version = '0.3.10' + s.version = '0.3.11' s.summary = 'A library that contains apimatic-apimatic-core logic and utilities for consuming REST APIs using Python SDKs generated '\ 'by APIMatic.' s.description = 'The APIMatic Core libraries provide a stable runtime that powers all the functionality of SDKs.'\ diff --git a/lib/apimatic-core/utilities/api_helper.rb b/lib/apimatic-core/utilities/api_helper.rb index 5d727a5..4660c0b 100644 --- a/lib/apimatic-core/utilities/api_helper.rb +++ b/lib/apimatic-core/utilities/api_helper.rb @@ -442,6 +442,24 @@ def self.map_response(obj, keys) val end + # Extracts additional properties from the hash. + # @param [Hash] hash The hash to extract additional properties from. + # @param [Proc] unboxing_function The deserializer to apply to each item in the hash. + # @return [Hash] A hash containing the additional properties and their values. + def get_additional_properties(hash, unboxing_function) + additional_properties = {} + + hash.each do |key, value| + begin + additional_properties[key] = unboxing_function.call(value) + rescue StandardError + # Ignore exceptions and continue + end + end + + additional_properties + end + # Get content-type depending on the value # @param [Object] value The value for which the content-type is resolved. def self.get_content_type(value) diff --git a/test/test-apimatic-core/utilities/api_helper_test.rb b/test/test-apimatic-core/utilities/api_helper_test.rb index bbad8bd..e7cad52 100644 --- a/test/test-apimatic-core/utilities/api_helper_test.rb +++ b/test/test-apimatic-core/utilities/api_helper_test.rb @@ -602,6 +602,36 @@ def test_deserialize_union_type ] assert_equal(expected, actual, 'Actual did not match the expected.') end + + def test_get_additional_properties_success + test_cases = [ + { dictionary: {}, expected_result: {}, unboxing_func: ->(x) { x.to_i }, is_dict: false }, + { dictionary: { "a" => 1, "b" => 2 }, expected_result: { "a" => 1, "b" => 2 }, unboxing_func: ->(x) { x.to_i }, is_dict: false }, + { dictionary: { "a" => "1", "b" => "2" }, expected_result: { "a" => "1", "b" => "2" }, unboxing_func: ->(x) { x.to_s }, is_dict: false }, + { dictionary: { "a" => "Test 1", "b" => "Test 2" }, expected_result: {}, unboxing_func: ->(x) { x.to_i }, is_dict: false }, + { dictionary: { "a" => [1, 2], "b" => [3, 4] }, expected_result: { "a" => [1, 2], "b" => [3, 4] }, unboxing_func: ->(x) { x.to_i }, is_dict: false }, + { dictionary: { "a" => { "x" => 1, "y" => 2 }, "b" => { "x" => 3, "y" => 4 } }, expected_result: { "a" => { "x" => 1, "y" => 2 }, "b" => { "x" => 3, "y" => 4 } }, unboxing_func: ->(x) { x.to_i }, is_dict: true } + ] + + test_cases.each do |case_data| + actual_result = ApiHelper.get_additional_properties(case_data[:dictionary], case_data[:unboxing_func]) + assert_equal(case_data[:expected_result], actual_result) + end + end + + def test_get_additional_properties_exception + test_cases = [ + { dictionary: { "a" => nil }, unboxing_func: Proc.new { |x| x } }, + { dictionary: { "a" => ->(x) { x } }, unboxing_func: Proc.new { |x| x }} + ] + + test_cases.each do |case_data| + actual_result = ApiHelper.get_additional_properties(case_data[:dictionary]) + expected_result = {} + assert_equal(expected_result, actual_result) + end + end + end From 69d210dfa5b78268bde693992fb92bcd4b8bbb54 Mon Sep 17 00:00:00 2001 From: MaryamAdnan3 Date: Tue, 5 Nov 2024 21:54:32 +0500 Subject: [PATCH 2/8] fix running api_helper tests --- lib/apimatic-core/utilities/api_helper.rb | 36 +++++++++++++++---- .../utilities/api_helper_test.rb | 19 +++++----- 2 files changed, 40 insertions(+), 15 deletions(-) diff --git a/lib/apimatic-core/utilities/api_helper.rb b/lib/apimatic-core/utilities/api_helper.rb index 4660c0b..61c3aac 100644 --- a/lib/apimatic-core/utilities/api_helper.rb +++ b/lib/apimatic-core/utilities/api_helper.rb @@ -442,24 +442,48 @@ def self.map_response(obj, keys) val end - # Extracts additional properties from the hash. + # Apply unboxing_function to additional properties from hash. # @param [Hash] hash The hash to extract additional properties from. # @param [Proc] unboxing_function The deserializer to apply to each item in the hash. # @return [Hash] A hash containing the additional properties and their values. - def get_additional_properties(hash, unboxing_function) + def self.get_additional_properties(hash, unboxing_function) additional_properties = {} - + + # Iterate over each key-value pair in the input hash hash.each do |key, value| begin - additional_properties[key] = unboxing_function.call(value) - rescue StandardError - # Ignore exceptions and continue + # If the value is a complex structure (Hash or Array), we apply apply_unboxing_function. + if value.is_a?(Hash) || value.is_a?(Array) + # Call apply_unboxing_function recursively if the value is a hash or array + additional_properties[key] = apply_unboxing_function(value, unboxing_function, as_dict: value.is_a?(Hash)) + else + # Apply the unboxing function directly for simple values + additional_properties[key] = unboxing_function.call(value) + end + rescue StandardError => e + # Optionally log the error message or handle it as needed + # puts "Error processing key '#{key}': #{e.message}" + # Ignore the exception and continue processing end end additional_properties end + + def self.apply_unboxing_function(obj, unboxing_function, as_dict: false) + if as_dict && obj.is_a?(Hash) + # If `obj` is a Hash and `as_dict` is true, apply the unboxing function to each value in the hash. + obj.transform_values { |v| apply_unboxing_function(v, unboxing_function, as_dict: true) } + elsif obj.is_a?(Array) + # If `obj` is an Array, apply the unboxing function to each element. + obj.map { |element| unboxing_function.call(element) } + else + # Otherwise, apply the unboxing function directly to the object. + unboxing_function.call(obj) + end + end + # Get content-type depending on the value # @param [Object] value The value for which the content-type is resolved. def self.get_content_type(value) diff --git a/test/test-apimatic-core/utilities/api_helper_test.rb b/test/test-apimatic-core/utilities/api_helper_test.rb index e7cad52..1ace9d3 100644 --- a/test/test-apimatic-core/utilities/api_helper_test.rb +++ b/test/test-apimatic-core/utilities/api_helper_test.rb @@ -605,12 +605,12 @@ def test_deserialize_union_type def test_get_additional_properties_success test_cases = [ - { dictionary: {}, expected_result: {}, unboxing_func: ->(x) { x.to_i }, is_dict: false }, - { dictionary: { "a" => 1, "b" => 2 }, expected_result: { "a" => 1, "b" => 2 }, unboxing_func: ->(x) { x.to_i }, is_dict: false }, - { dictionary: { "a" => "1", "b" => "2" }, expected_result: { "a" => "1", "b" => "2" }, unboxing_func: ->(x) { x.to_s }, is_dict: false }, - { dictionary: { "a" => "Test 1", "b" => "Test 2" }, expected_result: {}, unboxing_func: ->(x) { x.to_i }, is_dict: false }, - { dictionary: { "a" => [1, 2], "b" => [3, 4] }, expected_result: { "a" => [1, 2], "b" => [3, 4] }, unboxing_func: ->(x) { x.to_i }, is_dict: false }, - { dictionary: { "a" => { "x" => 1, "y" => 2 }, "b" => { "x" => 3, "y" => 4 } }, expected_result: { "a" => { "x" => 1, "y" => 2 }, "b" => { "x" => 3, "y" => 4 } }, unboxing_func: ->(x) { x.to_i }, is_dict: true } + { dictionary: {}, expected_result: {}, unboxing_func: Proc.new { |x| Integer(x) }}, + { dictionary: { "a" => 1, "b" => 2 }, expected_result: { "a" => 1, "b" => 2 }, unboxing_func: Proc.new { |x| Integer(x) }}, + { dictionary: { "a" => "1", "b" => "2" }, expected_result: { "a" => "1", "b" => "2" }, unboxing_func: Proc.new { |x| x.to_s }}, + { dictionary: { "a" => "Test 1", "b" => "Test 2" }, expected_result: {}, unboxing_func: Proc.new { |x| Integer(x) }, as_dict: false }, + { dictionary: { "a" => [1, 2], "b" => [3, 4] }, expected_result: { "a" => [1, 2], "b" => [3, 4] }, unboxing_func: Proc.new { |x| Integer(x) }}, + { dictionary: { "a" => { "x" => 1, "y" => 2 }, "b" => { "x" => 3, "y" => 4 } }, expected_result: { "a" => { "x" => 1, "y" => 2 }, "b" => { "x" => 3, "y" => 4 } }, unboxing_func: Proc.new { |x| Integer(x) }} ] test_cases.each do |case_data| @@ -619,14 +619,15 @@ def test_get_additional_properties_success end end + def test_get_additional_properties_exception test_cases = [ - { dictionary: { "a" => nil }, unboxing_func: Proc.new { |x| x } }, - { dictionary: { "a" => ->(x) { x } }, unboxing_func: Proc.new { |x| x }} + { dictionary: { "a" => nil }, unboxing_func: Proc.new { |x| Integer(x) } }, + { dictionary: { "a" => Proc.new { |x| x } }, unboxing_func: Proc.new { |x| Integer(x)}} ] test_cases.each do |case_data| - actual_result = ApiHelper.get_additional_properties(case_data[:dictionary]) + actual_result = ApiHelper.get_additional_properties(case_data[:dictionary], case_data[:unboxing_func]) expected_result = {} assert_equal(expected_result, actual_result) end From 3a913b54ceb23e915d2cc5cf5456b72f811e9ef8 Mon Sep 17 00:00:00 2001 From: MaryamAdnan3 Date: Wed, 6 Nov 2024 10:44:11 +0500 Subject: [PATCH 3/8] autofix rubocop issues --- lib/apimatic-core/utilities/api_helper.rb | 35 +++++++++++------------ 1 file changed, 16 insertions(+), 19 deletions(-) diff --git a/lib/apimatic-core/utilities/api_helper.rb b/lib/apimatic-core/utilities/api_helper.rb index 61c3aac..964a188 100644 --- a/lib/apimatic-core/utilities/api_helper.rb +++ b/lib/apimatic-core/utilities/api_helper.rb @@ -448,29 +448,26 @@ def self.map_response(obj, keys) # @return [Hash] A hash containing the additional properties and their values. def self.get_additional_properties(hash, unboxing_function) additional_properties = {} - + # Iterate over each key-value pair in the input hash hash.each do |key, value| - begin - # If the value is a complex structure (Hash or Array), we apply apply_unboxing_function. - if value.is_a?(Hash) || value.is_a?(Array) - # Call apply_unboxing_function recursively if the value is a hash or array - additional_properties[key] = apply_unboxing_function(value, unboxing_function, as_dict: value.is_a?(Hash)) - else - # Apply the unboxing function directly for simple values - additional_properties[key] = unboxing_function.call(value) - end - rescue StandardError => e - # Optionally log the error message or handle it as needed - # puts "Error processing key '#{key}': #{e.message}" - # Ignore the exception and continue processing - end + # If the value is a complex structure (Hash or Array), we apply apply_unboxing_function. + additional_properties[key] = if value.is_a?(Hash) || value.is_a?(Array) + # Call apply_unboxing_function recursively if the value is a hash or array + apply_unboxing_function(value, unboxing_function, as_dict: value.is_a?(Hash)) + else + # Apply the unboxing function directly for simple values + unboxing_function.call(value) + end + rescue StandardError + # Optionally log the error message or handle it as needed + # puts "Error processing key '#{key}': #{e.message}" + # Ignore the exception and continue processing end - + additional_properties end - - + def self.apply_unboxing_function(obj, unboxing_function, as_dict: false) if as_dict && obj.is_a?(Hash) # If `obj` is a Hash and `as_dict` is true, apply the unboxing function to each value in the hash. @@ -483,7 +480,7 @@ def self.apply_unboxing_function(obj, unboxing_function, as_dict: false) unboxing_function.call(obj) end end - + # Get content-type depending on the value # @param [Object] value The value for which the content-type is resolved. def self.get_content_type(value) From 9ba923d582338db79bc20479f5b0e3cff942ed8b Mon Sep 17 00:00:00 2001 From: MaryamAdnan3 Date: Fri, 8 Nov 2024 00:06:21 +0500 Subject: [PATCH 4/8] PR comments resolved --- lib/apimatic-core/utilities/api_helper.rb | 14 ++- .../utilities/api_helper_test.rb | 109 +++++++++++++++++- test/test-helper/mock_helper.rb | 47 ++++++++ test/test-helper/models/base_model.rb | 76 ++++++++---- ...ditional_properties_of_model_array_type.rb | 54 +++++++++ ...dditional_properties_of_model_dict_type.rb | 52 +++++++++ ...ith_additional_properties_of_model_type.rb | 54 +++++++++ ...onal_properties_of_primitive_array_type.rb | 51 ++++++++ ...ional_properties_of_primitive_dict_type.rb | 51 ++++++++ ...additional_properties_of_primitive_type.rb | 53 +++++++++ ...rties_of_type_combinator_primitive_type.rb | 53 +++++++++ test/test-helper/models/union_type_lookup.rb | 19 +++ 12 files changed, 598 insertions(+), 35 deletions(-) create mode 100644 test/test-helper/models/model_with_additional_properties_of_model_array_type.rb create mode 100644 test/test-helper/models/model_with_additional_properties_of_model_dict_type.rb create mode 100644 test/test-helper/models/model_with_additional_properties_of_model_type.rb create mode 100644 test/test-helper/models/model_with_additional_properties_of_primitive_array_type.rb create mode 100644 test/test-helper/models/model_with_additional_properties_of_primitive_dict_type.rb create mode 100644 test/test-helper/models/model_with_additional_properties_of_primitive_type.rb create mode 100644 test/test-helper/models/model_with_additional_properties_of_type_combinator_primitive_type.rb create mode 100644 test/test-helper/models/union_type_lookup.rb diff --git a/lib/apimatic-core/utilities/api_helper.rb b/lib/apimatic-core/utilities/api_helper.rb index 964a188..17d6468 100644 --- a/lib/apimatic-core/utilities/api_helper.rb +++ b/lib/apimatic-core/utilities/api_helper.rb @@ -446,15 +446,17 @@ def self.map_response(obj, keys) # @param [Hash] hash The hash to extract additional properties from. # @param [Proc] unboxing_function The deserializer to apply to each item in the hash. # @return [Hash] A hash containing the additional properties and their values. - def self.get_additional_properties(hash, unboxing_function) + def self.get_additional_properties(hash, unboxing_function, as_array: false, + as_dict: false) additional_properties = {} - # Iterate over each key-value pair in the input hash + # Iterate over each key-value pair in the input hash+ hash.each do |key, value| # If the value is a complex structure (Hash or Array), we apply apply_unboxing_function. - additional_properties[key] = if value.is_a?(Hash) || value.is_a?(Array) + additional_properties[key] = if as_array || as_dict # Call apply_unboxing_function recursively if the value is a hash or array - apply_unboxing_function(value, unboxing_function, as_dict: value.is_a?(Hash)) + apply_unboxing_function(value, unboxing_function, as_array: as_array, + as_dict: as_dict) else # Apply the unboxing function directly for simple values unboxing_function.call(value) @@ -468,11 +470,11 @@ def self.get_additional_properties(hash, unboxing_function) additional_properties end - def self.apply_unboxing_function(obj, unboxing_function, as_dict: false) + def self.apply_unboxing_function(obj, unboxing_function, as_array: false, as_dict: false) if as_dict && obj.is_a?(Hash) # If `obj` is a Hash and `as_dict` is true, apply the unboxing function to each value in the hash. obj.transform_values { |v| apply_unboxing_function(v, unboxing_function, as_dict: true) } - elsif obj.is_a?(Array) + elsif as_array && obj.is_a?(Array) # If `obj` is an Array, apply the unboxing function to each element. obj.map { |element| unboxing_function.call(element) } else diff --git a/test/test-apimatic-core/utilities/api_helper_test.rb b/test/test-apimatic-core/utilities/api_helper_test.rb index 1ace9d3..2437d5c 100644 --- a/test/test-apimatic-core/utilities/api_helper_test.rb +++ b/test/test-apimatic-core/utilities/api_helper_test.rb @@ -313,6 +313,35 @@ def test_form_encode end + def test_form_encoding_with_additional_props + key = "form_param" + test_cases = [ + [TestComponent::MockHelper.get_model_with_additional_properties_of_primitive_type_success, + { 'form_param[email]' => 'test@gmail.com', 'form_param[prop]' => 20 }], + [TestComponent::MockHelper.get_model_with_additional_properties_of_primitive_array_type, + { 'form_param[email]' => 'test@gmail.com', 'form_param[prop][0]' => 20, 'form_param[prop][1]' => 30 }], + [TestComponent::MockHelper.get_model_with_additional_properties_of_primitive_dict_type, + { 'form_param[email]' => 'test@gmail.com', 'form_param[prop][inner prop 1]' => 20, 'form_param[prop][inner prop 2]' => 30 }], + [TestComponent::MockHelper.get_model_with_additional_properties_of_model_type, + { 'form_param[email]' => 'test@gmail.com', "form_param[prop1][starts_at]"=>"8:00", "form_param[prop1][ends_at]"=>"10:00", "form_param[prop1][offer_dinner]"=> true, "form_param[prop1][session_type]"=>"Evening"}], + [TestComponent::MockHelper.get_model_with_additional_properties_of_model_array_type, + { 'form_param[email]' => 'test@gmail.com', + "form_param[prop1][0][starts_at]"=>"8:00", "form_param[prop1][0][ends_at]"=>"10:00", "form_param[prop1][0][offer_dinner]"=>true, "form_param[prop1][0][session_type]"=>"Evening", + "form_param[prop1][1][starts_at]"=>"8:00", "form_param[prop1][1][ends_at]"=>"10:00", "form_param[prop1][1][offer_dinner]"=>true, "form_param[prop1][1][session_type]"=>"Evening"}], + [TestComponent::MockHelper.get_model_with_additional_properties_of_model_dict_type, + {"form_param[email]"=>"test@gmail.com", + "form_param[prop1][inner_prop1][starts_at]"=>"8:00", "form_param[prop1][inner_prop1][ends_at]"=>"10:00", "form_param[prop1][inner_prop1][offer_dinner]"=>true, "form_param[prop1][inner_prop1][session_type]"=>"Evening", + "form_param[prop1][inner_prop2][starts_at]"=>"8:00", "form_param[prop1][inner_prop2][ends_at]"=>"10:00", "form_param[prop1][inner_prop2][offer_dinner]"=>true, "form_param[prop1][inner_prop2][session_type]"=>"Evening"}], + [TestComponent::MockHelper.get_model_with_additional_properties_of_type_combinator_primitive_type, + { 'form_param[email]' => 'test@gmail.com', 'form_param[prop]' => 10.55 }] + ] + + test_cases.each do |input_value, expected_form_params| + assert_equal(ApiHelper.form_encode(input_value, key, formatting: ArraySerializationFormat::INDEXED), + expected_form_params) + end + end + def test_custom_merge assert_equal(ApiHelper.custom_merge({ "number1" => 1, "string1" => ["a", "b", "d"], "same" => "c" }, { "number2" => 1, "string2" => ["d", "e"], "same" => "c" }), @@ -359,7 +388,27 @@ def test_json_serialize "\"birthtime\":\"2016-03-13T12:52:32+00:00\",\"name\":\"Jone\",\"uid\":\"1234\",\"personType\":\"Per\"}" ) assert_equal(ApiHelper.json_serialize(123), "123") + end + + def test_json_serialize_with_exception + test_cases = [ + [ + TestComponent::MockHelper.get_model_with_additional_properties_of_primitive_type, + "An additional property key, 'email' conflicts with one of the model's properties" + ] + ] + test_cases.each do |input_value, expected_validation_message| + assert_raises(StandardError) do + ApiHelper.json_serialize(input_value) + end + + begin + ApiHelper.json_serialize(input_value) + rescue StandardError => e + assert_equal expected_validation_message, e.message + end + end end def test_update_user_agent_value_with_parameters @@ -523,6 +572,58 @@ def test_valid_type_model_array_of_map is_model_hash: true, is_inner_model_hash: true) end + def json_deserialize + test_cases = [ + ['{"email": "test", "prop1": 1, "prop2": 2, "prop3": "invalid type"}', + TestComponent::ModelWithAdditionalPropertiesOfPrimitiveType, false, + '{"email": "test", "prop1": 1, "prop2": 2}'], + + ['{"email": "test", "prop1": [1, 2, 3], "prop2": [1, 2, 3], "prop3": "invalid type"}', + TestComponent::ModelWithAdditionalPropertiesOfPrimitiveArrayType, false, + '{"email": "test", "prop1": [1, 2, 3], "prop2": [1, 2, 3]}'], + + ['{"email": "test", "prop1": {"inner_prop1": 1, "inner_prop2": 2}, "prop2": {"inner_prop1": 1, "inner_prop2": 2}, "prop3": "invalid type"}', + TestComponent::ModelWithAdditionalPropertiesOfPrimitiveDictType, false, + '{"email": "test", "prop1": {"inner_prop1": 1, "inner_prop2": 2}, "prop2": {"inner_prop1": 1, "inner_prop2": 2}}'], + + ['{"email": "test", "prop1": {"id": 1, "weight": 50, "type": "Lion"}, "prop3": "invalid type"}', + TestComponent::ModelWithAdditionalPropertiesOfModelType, false, + '{"email": "test", "prop1": {"id": 1, "weight": 50, "type": "Lion"}}'], + + ['{"email": "test", "prop": [{"id": 1, "weight": 50, "type": "Lion"}, {"id": 2, "weight": 100, "type": "Lion"}]}', + TestComponent::ModelWithAdditionalPropertiesOfModelArrayType, false, + '{"email": "test", "prop": [{"id": 1, "weight": 50, "type": "Lion"}, {"id": 2, "weight": 100, "type": "Lion"}]}'], + + ['{"email": "test", "prop": {"inner prop 1": {"id": 1, "weight": 50, "type": "Lion"}, "inner prop 2": {"id": 2, "weight": 100, "type": "Lion"}}}', + TestComponent::ModelWithAdditionalPropertiesOfModelDictType, false, + '{"email": "test", "prop": {"inner prop 1": {"id": 1, "weight": 50, "type": "Lion"}, "inner prop 2": {"id": 2, "weight": 100, "type": "Lion"}}}'], + + ['{"email": "test", "prop": true}', + TestComponent::ModelWithAdditionalPropertiesOfTypeCombinatorPrimitive, false, + '{"email": "test", "prop": true}'], + + ['{"email": "test", "prop": 100.65}', + TestComponent::ModelWithAdditionalPropertiesOfTypeCombinatorPrimitive, false, + '{"email": "test", "prop": 100.65}'], + + ['{"email": "test", "prop": "100.65"}', + TestComponent::ModelWithAdditionalPropertiesOfTypeCombinatorPrimitive, false, + '{"email": "test"}'] + ] + + # Iterate through each test case + test_cases.each do |input_json_value, model_class, as_dict, expected_value| + deserialized_value = model_class.from_hash( + APIHelper.json_deserialize(input_json_value, as_dict) + ) + + serialized_value = APIHelper.json_serialize(deserialized_value) + + # Assert that the serialized value matches the expected value + assert_equal expected_value, serialized_value + end + end + def test_valid_type_hash assert ApiHelper.valid_type?( { @@ -608,13 +709,13 @@ def test_get_additional_properties_success { dictionary: {}, expected_result: {}, unboxing_func: Proc.new { |x| Integer(x) }}, { dictionary: { "a" => 1, "b" => 2 }, expected_result: { "a" => 1, "b" => 2 }, unboxing_func: Proc.new { |x| Integer(x) }}, { dictionary: { "a" => "1", "b" => "2" }, expected_result: { "a" => "1", "b" => "2" }, unboxing_func: Proc.new { |x| x.to_s }}, - { dictionary: { "a" => "Test 1", "b" => "Test 2" }, expected_result: {}, unboxing_func: Proc.new { |x| Integer(x) }, as_dict: false }, - { dictionary: { "a" => [1, 2], "b" => [3, 4] }, expected_result: { "a" => [1, 2], "b" => [3, 4] }, unboxing_func: Proc.new { |x| Integer(x) }}, - { dictionary: { "a" => { "x" => 1, "y" => 2 }, "b" => { "x" => 3, "y" => 4 } }, expected_result: { "a" => { "x" => 1, "y" => 2 }, "b" => { "x" => 3, "y" => 4 } }, unboxing_func: Proc.new { |x| Integer(x) }} + { dictionary: { "a" => "Test 1", "b" => "Test 2" }, expected_result: {}, unboxing_func: Proc.new { |x| Integer(x) }}, + { dictionary: { "a" => [1, 2], "b" => [3, 4] }, expected_result: { "a" => [1, 2], "b" => [3, 4] }, unboxing_func: Proc.new { |x| Integer(x) }, as_array: true}, + { dictionary: { "a" => { "x" => 1, "y" => 2 }, "b" => { "x" => 3, "y" => 4 } }, expected_result: { "a" => { "x" => 1, "y" => 2 }, "b" => { "x" => 3, "y" => 4 } }, unboxing_func: Proc.new { |x| Integer(x) }, as_array: false, as_dict: true} ] test_cases.each do |case_data| - actual_result = ApiHelper.get_additional_properties(case_data[:dictionary], case_data[:unboxing_func]) + actual_result = ApiHelper.get_additional_properties(case_data[:dictionary], case_data[:unboxing_func], as_array: case_data[:as_array], as_dict: case_data[:as_dict]) assert_equal(case_data[:expected_result], actual_result) end end diff --git a/test/test-helper/mock_helper.rb b/test/test-helper/mock_helper.rb index 0d1a805..df6b897 100644 --- a/test/test-helper/mock_helper.rb +++ b/test/test-helper/mock_helper.rb @@ -22,6 +22,13 @@ require_relative 'models/non_scalar_model' require_relative 'models/car' require_relative 'models/noon' +require_relative 'models/model_with_additional_properties_of_model_array_type' +require_relative 'models/model_with_additional_properties_of_model_dict_type' +require_relative 'models/model_with_additional_properties_of_model_type' +require_relative 'models/model_with_additional_properties_of_primitive_array_type' +require_relative 'models/model_with_additional_properties_of_primitive_dict_type' +require_relative 'models/model_with_additional_properties_of_primitive_type' +require_relative 'models/model_with_additional_properties_of_type_combinator_primitive_type' module TestComponent # An enum for SDK environments. @@ -192,5 +199,45 @@ def self.get_attributes_elements_model_with_datetime AttributesAndElements.new('string-attr', 2, 'string-element', DateTimeHelper.from_unix(1484719381)) end + + def self.get_model_with_additional_properties_of_primitive_type + model_with_additional_properties_of_primitive_type = ModelWithAdditionalPropertiesOfPrimitiveType.new("test@gmail.com", { 'email' => 10.55 }) + return model_with_additional_properties_of_primitive_type + end + + def self.get_model_with_additional_properties_of_primitive_type_success + model_with_additional_properties_of_primitive_type = ModelWithAdditionalPropertiesOfPrimitiveType.new("test@gmail.com", { 'prop' => 20 }) + return model_with_additional_properties_of_primitive_type + end + + def self.get_model_with_additional_properties_of_primitive_array_type + model_with_additional_properties_of_primitive_array_type = ModelWithAdditionalPropertiesOfPrimitiveArrayType.new('test@gmail.com', { 'prop' => [20, 30] }) + return model_with_additional_properties_of_primitive_array_type + end + + def self.get_model_with_additional_properties_of_primitive_dict_type + model_with_additional_properties_of_primitive_dict_type = ModelWithAdditionalPropertiesOfPrimitiveDictType.new("test@gmail.com", { 'prop' => { 'inner prop 1' => 20, 'inner prop 2' => 30 } }) + return model_with_additional_properties_of_primitive_dict_type + end + + def self.get_model_with_additional_properties_of_model_type + model_with_additional_properties_of_model_type = ModelWithAdditionalPropertiesOfModelType.new("test@gmail.com", "prop1": {"starts_at": "8:00", "ends_at": "10:00", "offer_dinner": true, "session_type": "Evening"}) + return model_with_additional_properties_of_model_type + end + + def self.get_model_with_additional_properties_of_model_array_type + model_with_additional_properties_of_model_array_type = ModelWithAdditionalPropertiesOfModelArrayType.new("test@gmail.com", "prop1": [{"starts_at": "8:00", "ends_at": "10:00", "offer_dinner": true, "session_type": "Evening"}, {"starts_at": "8:00", "ends_at": "10:00", "offer_dinner": true, "session_type": "Evening"}]) + return model_with_additional_properties_of_model_array_type + end + + def self.get_model_with_additional_properties_of_model_dict_type + model_with_additional_properties_of_model_dict_type = ModelWithAdditionalPropertiesOfModelDictType.new("test@gmail.com", "prop1": {"inner_prop1": {"starts_at": "8:00", "ends_at": "10:00", "offer_dinner": true, "session_type": "Evening"}, "inner_prop2": {"starts_at": "8:00", "ends_at": "10:00", "offer_dinner": true, "session_type": "Evening"}}) + return model_with_additional_properties_of_model_dict_type + end + + def self.get_model_with_additional_properties_of_type_combinator_primitive_type + model_with_additional_properties_of_type_combinator_primitive_type = ModelWithAdditionalPropertiesOfTypeCombinatorPrimitiveType.new("test@gmail.com",{ 'prop' => 10.55 }) + return model_with_additional_properties_of_type_combinator_primitive_type + end end end diff --git a/test/test-helper/models/base_model.rb b/test/test-helper/models/base_model.rb index 23007c4..4025fe7 100644 --- a/test/test-helper/models/base_model.rb +++ b/test/test-helper/models/base_model.rb @@ -12,43 +12,69 @@ def to_hash instance_variables.each do |name| value = instance_variable_get(name) name = name[1..] - key = self.class.names.key?(name) ? self.class.names[name] : name + if name == 'additional_properties' + additional_properties = process_additional_properties(value, self.class.names) + hash.merge!(additional_properties) + else + key = self.class.names.key?(name) ? self.class.names[name] : name - optional_fields = self.class.optionals - nullable_fields = self.class.nullables - if value.nil? - next unless nullable_fields.include?(name) + optional_fields = self.class.optionals + nullable_fields = self.class.nullables + if value.nil? + next unless nullable_fields.include?(name) - if !optional_fields.include?(name) && !nullable_fields.include?(name) - raise ArgumentError, - "`#{name}` cannot be nil in `#{self.class}`. Please specify a valid value." + if !optional_fields.include?(name) && !nullable_fields.include?(name) + raise ArgumentError, + "`#{name}` cannot be nil in `#{self.class}`. Please specify a valid value." + end end - end - hash[key] = nil - unless value.nil? - if respond_to?("to_#{name}") - if (value.instance_of? Array) || (value.instance_of? Hash) - params = [hash, key] - hash[key] = send("to_#{name}", *params) + hash[key] = nil + unless value.nil? + if respond_to?("to_#{name}") + if (value.instance_of? Array) || (value.instance_of? Hash) + params = [hash, key] + hash[key] = send("to_#{name}", *params) + else + hash[key] = send("to_#{name}") + end + elsif value.instance_of? Array + hash[key] = value.map { |v| v.is_a?(BaseModel) ? v.to_hash : v } + elsif value.instance_of? Hash + hash[key] = {} + value.each do |k, v| + hash[key][k] = v.is_a?(BaseModel) ? v.to_hash : v + end else - hash[key] = send("to_#{name}") - end - elsif value.instance_of? Array - hash[key] = value.map { |v| v.is_a?(BaseModel) ? v.to_hash : v } - elsif value.instance_of? Hash - hash[key] = {} - value.each do |k, v| - hash[key][k] = v.is_a?(BaseModel) ? v.to_hash : v + hash[key] = value.is_a?(BaseModel) ? value.to_hash : value end - else - hash[key] = value.is_a?(BaseModel) ? value.to_hash : value end end end hash end + def process_additional_properties(additional_properties, existing_prop_names) + hash = {} + additional_properties.each do |name, value| + if existing_prop_names.key?(name) + raise ArgumentError, "An additional property key, '#{name}' conflicts with one of the model's properties" + end + + if value.is_a?(Array) + hash[name] = value.map { |item| item.is_a?(BaseModel) ? item.to_hash : item } + elsif value.is_a?(Hash) + hash[name] = {} + value.each do |k, v| + hash[name][k] = v.is_a?(BaseModel) ? v.to_hash : v + end + else + hash[name] = value.is_a?(BaseModel) ? value.to_hash : value + end + end + hash + end + # Returns a JSON representation of the curent object. def to_json(options = {}) hash = to_hash diff --git a/test/test-helper/models/model_with_additional_properties_of_model_array_type.rb b/test/test-helper/models/model_with_additional_properties_of_model_array_type.rb new file mode 100644 index 0000000..75eb5d3 --- /dev/null +++ b/test/test-helper/models/model_with_additional_properties_of_model_array_type.rb @@ -0,0 +1,54 @@ +require_relative '../models/base_model' +require_relative '../models/evening' + +module TestComponent + class ModelWithAdditionalPropertiesOfModelArrayType < BaseModel + SKIP = Object.new + private_constant :SKIP + + # TODO: Write general description for this method + # @return [String] + attr_accessor :email + + # A mapping from model property names to API property names. + def self.names + @_hash = {} if @_hash.nil? + @_hash['email'] = 'email' + @_hash + end + + # An array for optional fields + def self.optionals + [] + end + + # An array for nullable fields + def self.nullables + [] + end + + def initialize(email = nil, additional_properties = nil) + additional_properties = {} if additional_properties.nil? + + @email = email + @additional_properties = additional_properties + end + + # Creates an instance of the object from a hash. + def self.from_hash(hash) + return nil unless hash + + # Extract variables from the hash. + email = hash.key?('email') ? hash['email'] : nil + + # Create a new hash for additional properties, removing known properties. + new_hash = hash.reject { |key, _| self.names.key?(key) } + + additional_properties = CoreLibrary::APIHelper.get_additional_properties( + new_hash, Proc.new { |item| Evening.from_dictionary(item) }, as_array: true) + + # Create object from extracted values. + ModelWithAdditionalPropertiesOfModelArrayType.new(email, additional_properties) + end + end +end \ No newline at end of file diff --git a/test/test-helper/models/model_with_additional_properties_of_model_dict_type.rb b/test/test-helper/models/model_with_additional_properties_of_model_dict_type.rb new file mode 100644 index 0000000..fb64f95 --- /dev/null +++ b/test/test-helper/models/model_with_additional_properties_of_model_dict_type.rb @@ -0,0 +1,52 @@ +require_relative '../models/base_model' +require_relative '../models/evening' + +class ModelWithAdditionalPropertiesOfModelDictType < TestComponent::BaseModel + SKIP = Object.new + private_constant :SKIP + + # TODO: Write general description for this method + # @return [String] + attr_accessor :email + + # A mapping from model property names to API property names. + def self.names + @_hash = {} if @_hash.nil? + @_hash['email'] = 'email' + @_hash + end + + # An array for optional fields + def self.optionals + [] + end + + # An array for nullable fields + def self.nullables + [] + end + + def initialize(email = nil, additional_properties = nil) + additional_properties = {} if additional_properties.nil? + + @email = email + @additional_properties = additional_properties + end + + # Creates an instance of the object from a hash. + def self.from_hash(hash) + return nil unless hash + + # Extract variables from the hash. + email = hash.key?('email') ? hash['email'] : nil + + # Create a new hash for additional properties, removing known properties. + new_hash = hash.reject { |key, _| self.names.key?(key) } + + additional_properties = CoreLibrary::APIHelper.get_additional_properties( + new_hash, Proc.new { |item| Evening.from_dictionary(item) }, as_dict: true) + + # Create object from extracted values. + ModelWithAdditionalPropertiesOfModelDictType.new(email, additional_properties) + end +end \ No newline at end of file diff --git a/test/test-helper/models/model_with_additional_properties_of_model_type.rb b/test/test-helper/models/model_with_additional_properties_of_model_type.rb new file mode 100644 index 0000000..a72a870 --- /dev/null +++ b/test/test-helper/models/model_with_additional_properties_of_model_type.rb @@ -0,0 +1,54 @@ +require_relative '../models/base_model' +require_relative '../models/evening' + +module TestComponent + class ModelWithAdditionalPropertiesOfModelType < BaseModel + SKIP = Object.new + private_constant :SKIP + + # TODO: Write general description for this method + # @return [String] + attr_accessor :email + + # A mapping from model property names to API property names. + def self.names + @_hash = {} if @_hash.nil? + @_hash['email'] = 'email' + @_hash + end + + # An array for optional fields + def self.optionals + [] + end + + # An array for nullable fields + def self.nullables + [] + end + + def initialize(email = nil, additional_properties = nil) + additional_properties = {} if additional_properties.nil? + + @email = email + @additional_properties = additional_properties + end + + # Creates an instance of the object from a hash. + def self.from_hash(hash) + return nil unless hash + + # Extract variables from the hash. + email = hash.key?('email') ? hash['email'] : nil + + # Create a new hash for additional properties, removing known properties. + new_hash = hash.reject { |key, _| self.names.key?(key) } + + additional_properties = CoreLibrary::APIHelper.get_additional_properties( + new_hash, Proc.new { |item| Evening.from_dictionary(item) }) + + # Create object from extracted values. + ModelWithAdditionalPropertiesOfModelType.new(email, additional_properties) + end + end +end \ No newline at end of file diff --git a/test/test-helper/models/model_with_additional_properties_of_primitive_array_type.rb b/test/test-helper/models/model_with_additional_properties_of_primitive_array_type.rb new file mode 100644 index 0000000..6748107 --- /dev/null +++ b/test/test-helper/models/model_with_additional_properties_of_primitive_array_type.rb @@ -0,0 +1,51 @@ +require_relative '../models/base_model' + +class ModelWithAdditionalPropertiesOfPrimitiveArrayType < TestComponent::BaseModel + SKIP = Object.new + private_constant :SKIP + + # TODO: Write general description for this method + # @return [String] + attr_accessor :email + + # A mapping from model property names to API property names. + def self.names + @_hash = {} if @_hash.nil? + @_hash['email'] = 'email' + @_hash + end + + # An array for optional fields + def self.optionals + [] + end + + # An array for nullable fields + def self.nullables + [] + end + + def initialize(email = nil, additional_properties = nil) + additional_properties = {} if additional_properties.nil? + + @email = email + @additional_properties = additional_properties + end + + # Creates an instance of the object from a hash. + def self.from_hash(hash) + return nil unless hash + + # Extract variables from the hash. + email = hash.key?('email') ? hash['email'] : nil + + # Create a new hash for additional properties, removing known properties. + new_hash = hash.reject { |key, _| self.names.key?(key) } + + additional_properties = CoreLibrary::APIHelper.get_additional_properties( + new_hash, Proc.new { |x| Integer(x) }, as_array: true) + + # Create object from extracted values. + ModelWithAdditionalPropertiesOfPrimitiveArrayType.new(email, additional_properties) + end +end \ No newline at end of file diff --git a/test/test-helper/models/model_with_additional_properties_of_primitive_dict_type.rb b/test/test-helper/models/model_with_additional_properties_of_primitive_dict_type.rb new file mode 100644 index 0000000..1f59e01 --- /dev/null +++ b/test/test-helper/models/model_with_additional_properties_of_primitive_dict_type.rb @@ -0,0 +1,51 @@ +require_relative '../models/base_model' + +class ModelWithAdditionalPropertiesOfPrimitiveDictType < TestComponent::BaseModel + SKIP = Object.new + private_constant :SKIP + + # TODO: Write general description for this method + # @return [String] + attr_accessor :email + + # A mapping from model property names to API property names. + def self.names + @_hash = {} if @_hash.nil? + @_hash['email'] = 'email' + @_hash + end + + # An array for optional fields + def self.optionals + [] + end + + # An array for nullable fields + def self.nullables + [] + end + + def initialize(email = nil, additional_properties = nil) + additional_properties = {} if additional_properties.nil? + + @email = email + @additional_properties = additional_properties + end + + # Creates an instance of the object from a hash. + def self.from_hash(hash) + return nil unless hash + + # Extract variables from the hash. + email = hash.key?('email') ? hash['email'] : nil + + # Create a new hash for additional properties, removing known properties. + new_hash = hash.reject { |key, _| self.names.key?(key) } + + additional_properties = CoreLibrary::APIHelper.get_additional_properties( + new_hash, Proc.new { |x| Integer(x) }, as_array: false, as_dict: true) + + # Create object from extracted values. + ModelWithAdditionalPropertiesOfPrimitiveDictType.new(email, additional_properties) + end +end \ No newline at end of file diff --git a/test/test-helper/models/model_with_additional_properties_of_primitive_type.rb b/test/test-helper/models/model_with_additional_properties_of_primitive_type.rb new file mode 100644 index 0000000..9befe46 --- /dev/null +++ b/test/test-helper/models/model_with_additional_properties_of_primitive_type.rb @@ -0,0 +1,53 @@ +require_relative '../models/base_model' + +module TestComponent + class ModelWithAdditionalPropertiesOfPrimitiveType < TestComponent::BaseModel + SKIP = Object.new + private_constant :SKIP + + # TODO: Write general description for this method + # @return [String] + attr_accessor :email + + # A mapping from model property names to API property names. + def self.names + @_hash = {} if @_hash.nil? + @_hash['email'] = 'email' + @_hash + end + + # An array for optional fields + def self.optionals + [] + end + + # An array for nullable fields + def self.nullables + [] + end + + def initialize(email = nil, additional_properties = nil) + additional_properties = {} if additional_properties.nil? + + @email = email + @additional_properties = additional_properties + end + + # Creates an instance of the object from a hash. + def self.from_hash(hash) + return nil unless hash + + # Extract variables from the hash. + email = hash.key?('email') ? hash['email'] : nil + + # Create a new hash for additional properties, removing known properties. + new_hash = hash.reject { |key, _| self.names.key?(key) } + + additional_properties = APIHelper.get_additional_properties( + new_hash, Proc.new { |x| Integer(x) }) + + # Create object from extracted values. + ModelWithAdditionalPropertiesOfPrimitiveType.new(email, additional_properties) + end + end +end \ No newline at end of file diff --git a/test/test-helper/models/model_with_additional_properties_of_type_combinator_primitive_type.rb b/test/test-helper/models/model_with_additional_properties_of_type_combinator_primitive_type.rb new file mode 100644 index 0000000..01f8c09 --- /dev/null +++ b/test/test-helper/models/model_with_additional_properties_of_type_combinator_primitive_type.rb @@ -0,0 +1,53 @@ +require_relative '../models/base_model' +require_relative '../models/evening' + +class ModelWithAdditionalPropertiesOfTypeCombinatorPrimitiveType < TestComponent::BaseModel + SKIP = Object.new + private_constant :SKIP + + # TODO: Write general description for this method + # @return [String] + attr_accessor :email + + # A mapping from model property names to API property names. + def self.names + @_hash = {} if @_hash.nil? + @_hash['email'] = 'email' + @_hash + end + + # An array for optional fields + def self.optionals + [] + end + + # An array for nullable fields + def self.nullables + [] + end + + def initialize(email = nil, additional_properties = nil) + additional_properties = {} if additional_properties.nil? + + @email = email + @additional_properties = additional_properties + end + + # Creates an instance of the object from a hash. + def self.from_hash(hash) + return nil unless hash + + # Extract variables from the hash. + email = hash.key?('email') ? hash['email'] : nil + + # Create a new hash for additional properties, removing known properties. + new_hash = hash.reject { |key, _| self.names.key?(key) } + + additional_properties = CoreLibrary::APIHelper.get_additional_properties( + new_hash, Proc.new { |x| CoreLibrary::ApiHelper.deserialize_union_type(UnionTypeLookUp.get('scalarModelAnyOfRequired'), + x)}) + + # Create object from extracted values. + ModelWithAdditionalPropertiesOfTypeCombinatorPrimitiveType.new(email, additional_properties) + end +end \ No newline at end of file diff --git a/test/test-helper/models/union_type_lookup.rb b/test/test-helper/models/union_type_lookup.rb new file mode 100644 index 0000000..3a8654d --- /dev/null +++ b/test/test-helper/models/union_type_lookup.rb @@ -0,0 +1,19 @@ +class UnionTypeLookUp + # The `_union_types` stores type combinators as class variables (similar to a dictionary) + # in Python, which is equivalent to a hash in Ruby. + + # Store the union types as a class variable. + # The format `UnionTypeLookUp._union_types` is similar to the Python class-level dictionary. + @union_types = { + 'ScalarModelAnyOfRequired' => CoreLibrary::AnyOf.new([CoreLibrary::LeafType.new(Float), CoreLibrary::LeafType.new(TrueClass)]), + 'ScalarModelOneOfReqNullable' => CoreLibrary::OneOf.new([CoreLibrary::LeafType.new(Integer), CoreLibrary::LeafType.new(String)], CoreLibrary::UnionTypeContext.create(is_nullable: true)), + 'ScalarModelOneOfOptional' => CoreLibrary::OneOf.new([CoreLibrary::LeafType.new(Integer), CoreLibrary::LeafType.new(Float), CoreLibrary::UnionTypeContext.new(String)], CoreLibrary::UnionTypeContext.create(is_optional: true)), + 'ScalarModelAnyOfOptNullable' => CoreLibrary::AnyOf.new([CoreLibrary::LeafType.new(Integer), CoreLibrary::LeafType.new(TrueClass)], CoreLibrary::UnionTypeContext.create(is_optional: true, is_nullable: true)), + 'ScalarTypes' => CoreLibrary::OneOf.new([CoreLibrary::LeafType.new(Float), CoreLibrary::LeafType.new(TrueClass)]) + } + + # This is a getter method to access the union types by name. + def self.get(name) + @union_types[name] + end +end \ No newline at end of file From 05173e2658370bd88ff45e9e0ee3c47a2a29aa80 Mon Sep 17 00:00:00 2001 From: MaryamAdnan3 Date: Fri, 8 Nov 2024 09:47:20 +0500 Subject: [PATCH 5/8] minor refactoring --- ...ditional_properties_of_model_array_type.rb | 1 - ...dditional_properties_of_model_dict_type.rb | 95 +++++++++--------- ...ith_additional_properties_of_model_type.rb | 1 - ...onal_properties_of_primitive_array_type.rb | 95 +++++++++--------- ...ional_properties_of_primitive_dict_type.rb | 95 +++++++++--------- ...additional_properties_of_primitive_type.rb | 3 +- ...rties_of_type_combinator_primitive_type.rb | 97 ++++++++++--------- 7 files changed, 194 insertions(+), 193 deletions(-) diff --git a/test/test-helper/models/model_with_additional_properties_of_model_array_type.rb b/test/test-helper/models/model_with_additional_properties_of_model_array_type.rb index 75eb5d3..238f069 100644 --- a/test/test-helper/models/model_with_additional_properties_of_model_array_type.rb +++ b/test/test-helper/models/model_with_additional_properties_of_model_array_type.rb @@ -6,7 +6,6 @@ class ModelWithAdditionalPropertiesOfModelArrayType < BaseModel SKIP = Object.new private_constant :SKIP - # TODO: Write general description for this method # @return [String] attr_accessor :email diff --git a/test/test-helper/models/model_with_additional_properties_of_model_dict_type.rb b/test/test-helper/models/model_with_additional_properties_of_model_dict_type.rb index fb64f95..0eb1c52 100644 --- a/test/test-helper/models/model_with_additional_properties_of_model_dict_type.rb +++ b/test/test-helper/models/model_with_additional_properties_of_model_dict_type.rb @@ -1,52 +1,53 @@ require_relative '../models/base_model' require_relative '../models/evening' -class ModelWithAdditionalPropertiesOfModelDictType < TestComponent::BaseModel - SKIP = Object.new - private_constant :SKIP - - # TODO: Write general description for this method - # @return [String] - attr_accessor :email - - # A mapping from model property names to API property names. - def self.names - @_hash = {} if @_hash.nil? - @_hash['email'] = 'email' - @_hash - end - - # An array for optional fields - def self.optionals - [] - end - - # An array for nullable fields - def self.nullables - [] - end - - def initialize(email = nil, additional_properties = nil) - additional_properties = {} if additional_properties.nil? - - @email = email - @additional_properties = additional_properties - end - - # Creates an instance of the object from a hash. - def self.from_hash(hash) - return nil unless hash - - # Extract variables from the hash. - email = hash.key?('email') ? hash['email'] : nil - - # Create a new hash for additional properties, removing known properties. - new_hash = hash.reject { |key, _| self.names.key?(key) } - - additional_properties = CoreLibrary::APIHelper.get_additional_properties( - new_hash, Proc.new { |item| Evening.from_dictionary(item) }, as_dict: true) - - # Create object from extracted values. - ModelWithAdditionalPropertiesOfModelDictType.new(email, additional_properties) +module TestComponent + class ModelWithAdditionalPropertiesOfModelDictType < BaseModel + SKIP = Object.new + private_constant :SKIP + + # @return [String] + attr_accessor :email + + # A mapping from model property names to API property names. + def self.names + @_hash = {} if @_hash.nil? + @_hash['email'] = 'email' + @_hash + end + + # An array for optional fields + def self.optionals + [] + end + + # An array for nullable fields + def self.nullables + [] + end + + def initialize(email = nil, additional_properties = nil) + additional_properties = {} if additional_properties.nil? + + @email = email + @additional_properties = additional_properties + end + + # Creates an instance of the object from a hash. + def self.from_hash(hash) + return nil unless hash + + # Extract variables from the hash. + email = hash.key?('email') ? hash['email'] : nil + + # Create a new hash for additional properties, removing known properties. + new_hash = hash.reject { |key, _| self.names.key?(key) } + + additional_properties = CoreLibrary::APIHelper.get_additional_properties( + new_hash, Proc.new { |item| Evening.from_dictionary(item) }, as_dict: true) + + # Create object from extracted values. + ModelWithAdditionalPropertiesOfModelDictType.new(email, additional_properties) + end end end \ No newline at end of file diff --git a/test/test-helper/models/model_with_additional_properties_of_model_type.rb b/test/test-helper/models/model_with_additional_properties_of_model_type.rb index a72a870..b8fd7c6 100644 --- a/test/test-helper/models/model_with_additional_properties_of_model_type.rb +++ b/test/test-helper/models/model_with_additional_properties_of_model_type.rb @@ -6,7 +6,6 @@ class ModelWithAdditionalPropertiesOfModelType < BaseModel SKIP = Object.new private_constant :SKIP - # TODO: Write general description for this method # @return [String] attr_accessor :email diff --git a/test/test-helper/models/model_with_additional_properties_of_primitive_array_type.rb b/test/test-helper/models/model_with_additional_properties_of_primitive_array_type.rb index 6748107..e38d916 100644 --- a/test/test-helper/models/model_with_additional_properties_of_primitive_array_type.rb +++ b/test/test-helper/models/model_with_additional_properties_of_primitive_array_type.rb @@ -1,51 +1,52 @@ require_relative '../models/base_model' -class ModelWithAdditionalPropertiesOfPrimitiveArrayType < TestComponent::BaseModel - SKIP = Object.new - private_constant :SKIP - - # TODO: Write general description for this method - # @return [String] - attr_accessor :email - - # A mapping from model property names to API property names. - def self.names - @_hash = {} if @_hash.nil? - @_hash['email'] = 'email' - @_hash - end - - # An array for optional fields - def self.optionals - [] - end - - # An array for nullable fields - def self.nullables - [] - end - - def initialize(email = nil, additional_properties = nil) - additional_properties = {} if additional_properties.nil? - - @email = email - @additional_properties = additional_properties - end - - # Creates an instance of the object from a hash. - def self.from_hash(hash) - return nil unless hash - - # Extract variables from the hash. - email = hash.key?('email') ? hash['email'] : nil - - # Create a new hash for additional properties, removing known properties. - new_hash = hash.reject { |key, _| self.names.key?(key) } - - additional_properties = CoreLibrary::APIHelper.get_additional_properties( - new_hash, Proc.new { |x| Integer(x) }, as_array: true) - - # Create object from extracted values. - ModelWithAdditionalPropertiesOfPrimitiveArrayType.new(email, additional_properties) +module TestComponent + class ModelWithAdditionalPropertiesOfPrimitiveArrayType < BaseModel + SKIP = Object.new + private_constant :SKIP + + # @return [String] + attr_accessor :email + + # A mapping from model property names to API property names. + def self.names + @_hash = {} if @_hash.nil? + @_hash['email'] = 'email' + @_hash + end + + # An array for optional fields + def self.optionals + [] + end + + # An array for nullable fields + def self.nullables + [] + end + + def initialize(email = nil, additional_properties = nil) + additional_properties = {} if additional_properties.nil? + + @email = email + @additional_properties = additional_properties + end + + # Creates an instance of the object from a hash. + def self.from_hash(hash) + return nil unless hash + + # Extract variables from the hash. + email = hash.key?('email') ? hash['email'] : nil + + # Create a new hash for additional properties, removing known properties. + new_hash = hash.reject { |key, _| self.names.key?(key) } + + additional_properties = CoreLibrary::APIHelper.get_additional_properties( + new_hash, Proc.new { |x| Integer(x) }, as_array: true) + + # Create object from extracted values. + ModelWithAdditionalPropertiesOfPrimitiveArrayType.new(email, additional_properties) + end end end \ No newline at end of file diff --git a/test/test-helper/models/model_with_additional_properties_of_primitive_dict_type.rb b/test/test-helper/models/model_with_additional_properties_of_primitive_dict_type.rb index 1f59e01..19876e5 100644 --- a/test/test-helper/models/model_with_additional_properties_of_primitive_dict_type.rb +++ b/test/test-helper/models/model_with_additional_properties_of_primitive_dict_type.rb @@ -1,51 +1,52 @@ require_relative '../models/base_model' -class ModelWithAdditionalPropertiesOfPrimitiveDictType < TestComponent::BaseModel - SKIP = Object.new - private_constant :SKIP - - # TODO: Write general description for this method - # @return [String] - attr_accessor :email - - # A mapping from model property names to API property names. - def self.names - @_hash = {} if @_hash.nil? - @_hash['email'] = 'email' - @_hash - end - - # An array for optional fields - def self.optionals - [] - end - - # An array for nullable fields - def self.nullables - [] - end - - def initialize(email = nil, additional_properties = nil) - additional_properties = {} if additional_properties.nil? - - @email = email - @additional_properties = additional_properties - end - - # Creates an instance of the object from a hash. - def self.from_hash(hash) - return nil unless hash - - # Extract variables from the hash. - email = hash.key?('email') ? hash['email'] : nil - - # Create a new hash for additional properties, removing known properties. - new_hash = hash.reject { |key, _| self.names.key?(key) } - - additional_properties = CoreLibrary::APIHelper.get_additional_properties( - new_hash, Proc.new { |x| Integer(x) }, as_array: false, as_dict: true) - - # Create object from extracted values. - ModelWithAdditionalPropertiesOfPrimitiveDictType.new(email, additional_properties) +module TestComponent + class ModelWithAdditionalPropertiesOfPrimitiveDictType < BaseModel + SKIP = Object.new + private_constant :SKIP + + # @return [String] + attr_accessor :email + + # A mapping from model property names to API property names. + def self.names + @_hash = {} if @_hash.nil? + @_hash['email'] = 'email' + @_hash + end + + # An array for optional fields + def self.optionals + [] + end + + # An array for nullable fields + def self.nullables + [] + end + + def initialize(email = nil, additional_properties = nil) + additional_properties = {} if additional_properties.nil? + + @email = email + @additional_properties = additional_properties + end + + # Creates an instance of the object from a hash. + def self.from_hash(hash) + return nil unless hash + + # Extract variables from the hash. + email = hash.key?('email') ? hash['email'] : nil + + # Create a new hash for additional properties, removing known properties. + new_hash = hash.reject { |key, _| self.names.key?(key) } + + additional_properties = CoreLibrary::APIHelper.get_additional_properties( + new_hash, Proc.new { |x| Integer(x) }, as_array: false, as_dict: true) + + # Create object from extracted values. + ModelWithAdditionalPropertiesOfPrimitiveDictType.new(email, additional_properties) + end end end \ No newline at end of file diff --git a/test/test-helper/models/model_with_additional_properties_of_primitive_type.rb b/test/test-helper/models/model_with_additional_properties_of_primitive_type.rb index 9befe46..402235f 100644 --- a/test/test-helper/models/model_with_additional_properties_of_primitive_type.rb +++ b/test/test-helper/models/model_with_additional_properties_of_primitive_type.rb @@ -1,11 +1,10 @@ require_relative '../models/base_model' module TestComponent - class ModelWithAdditionalPropertiesOfPrimitiveType < TestComponent::BaseModel + class ModelWithAdditionalPropertiesOfPrimitiveType < BaseModel SKIP = Object.new private_constant :SKIP - # TODO: Write general description for this method # @return [String] attr_accessor :email diff --git a/test/test-helper/models/model_with_additional_properties_of_type_combinator_primitive_type.rb b/test/test-helper/models/model_with_additional_properties_of_type_combinator_primitive_type.rb index 01f8c09..19b8615 100644 --- a/test/test-helper/models/model_with_additional_properties_of_type_combinator_primitive_type.rb +++ b/test/test-helper/models/model_with_additional_properties_of_type_combinator_primitive_type.rb @@ -1,53 +1,54 @@ require_relative '../models/base_model' require_relative '../models/evening' -class ModelWithAdditionalPropertiesOfTypeCombinatorPrimitiveType < TestComponent::BaseModel - SKIP = Object.new - private_constant :SKIP - - # TODO: Write general description for this method - # @return [String] - attr_accessor :email - - # A mapping from model property names to API property names. - def self.names - @_hash = {} if @_hash.nil? - @_hash['email'] = 'email' - @_hash - end - - # An array for optional fields - def self.optionals - [] - end - - # An array for nullable fields - def self.nullables - [] - end - - def initialize(email = nil, additional_properties = nil) - additional_properties = {} if additional_properties.nil? - - @email = email - @additional_properties = additional_properties - end - - # Creates an instance of the object from a hash. - def self.from_hash(hash) - return nil unless hash - - # Extract variables from the hash. - email = hash.key?('email') ? hash['email'] : nil - - # Create a new hash for additional properties, removing known properties. - new_hash = hash.reject { |key, _| self.names.key?(key) } - - additional_properties = CoreLibrary::APIHelper.get_additional_properties( - new_hash, Proc.new { |x| CoreLibrary::ApiHelper.deserialize_union_type(UnionTypeLookUp.get('scalarModelAnyOfRequired'), - x)}) - - # Create object from extracted values. - ModelWithAdditionalPropertiesOfTypeCombinatorPrimitiveType.new(email, additional_properties) +module TestComponent + class ModelWithAdditionalPropertiesOfTypeCombinatorPrimitiveType < BaseModel + SKIP = Object.new + private_constant :SKIP + + # @return [String] + attr_accessor :email + + # A mapping from model property names to API property names. + def self.names + @_hash = {} if @_hash.nil? + @_hash['email'] = 'email' + @_hash + end + + # An array for optional fields + def self.optionals + [] + end + + # An array for nullable fields + def self.nullables + [] + end + + def initialize(email = nil, additional_properties = nil) + additional_properties = {} if additional_properties.nil? + + @email = email + @additional_properties = additional_properties + end + + # Creates an instance of the object from a hash. + def self.from_hash(hash) + return nil unless hash + + # Extract variables from the hash. + email = hash.key?('email') ? hash['email'] : nil + + # Create a new hash for additional properties, removing known properties. + new_hash = hash.reject { |key, _| self.names.key?(key) } + + additional_properties = CoreLibrary::APIHelper.get_additional_properties( + new_hash, Proc.new { |x| CoreLibrary::ApiHelper.deserialize_union_type(UnionTypeLookUp.get('scalarModelAnyOfRequired'), + x)}) + + # Create object from extracted values. + ModelWithAdditionalPropertiesOfTypeCombinatorPrimitiveType.new(email, additional_properties) + end end end \ No newline at end of file From e73c2527c8c34d4636cd0bcbf2c401cb877b9c01 Mon Sep 17 00:00:00 2001 From: MaryamAdnan3 Date: Mon, 11 Nov 2024 14:13:00 +0500 Subject: [PATCH 6/8] added array_of_map and map_of_array cases and fixed duplication issues by introducing inheritence --- lib/apimatic-core/utilities/api_helper.rb | 62 +++++++++++++------ .../utilities/api_helper_test.rb | 58 ++++++++++++++--- .../models/base_with_additional_properties.rb | 50 +++++++++++++++ ...ditional_properties_of_model_array_type.rb | 62 ++++--------------- ...dditional_properties_of_model_dict_type.rb | 60 ++++-------------- ...ith_additional_properties_of_model_type.rb | 56 +++-------------- ...onal_properties_of_primitive_array_type.rb | 57 +++-------------- ...ional_properties_of_primitive_dict_type.rb | 60 ++++-------------- ...additional_properties_of_primitive_type.rb | 57 +++-------------- ...rties_of_type_combinator_primitive_type.rb | 58 +++-------------- 10 files changed, 220 insertions(+), 360 deletions(-) create mode 100644 test/test-helper/models/base_with_additional_properties.rb diff --git a/lib/apimatic-core/utilities/api_helper.rb b/lib/apimatic-core/utilities/api_helper.rb index 17d6468..29d6ac8 100644 --- a/lib/apimatic-core/utilities/api_helper.rb +++ b/lib/apimatic-core/utilities/api_helper.rb @@ -446,39 +446,65 @@ def self.map_response(obj, keys) # @param [Hash] hash The hash to extract additional properties from. # @param [Proc] unboxing_function The deserializer to apply to each item in the hash. # @return [Hash] A hash containing the additional properties and their values. - def self.get_additional_properties(hash, unboxing_function, as_array: false, - as_dict: false) + def self.get_additional_properties(hash, unboxing_function, is_array: false, is_dict: false, is_array_of_map: false, + is_map_of_array: false, dimension_count: 1) additional_properties = {} - # Iterate over each key-value pair in the input hash+ + # Iterate over each key-value pair in the input hash hash.each do |key, value| - # If the value is a complex structure (Hash or Array), we apply apply_unboxing_function. - additional_properties[key] = if as_array || as_dict - # Call apply_unboxing_function recursively if the value is a hash or array - apply_unboxing_function(value, unboxing_function, as_array: as_array, - as_dict: as_dict) + # Prepare arguments for apply_unboxing_function + args = { + is_array: is_array, + is_dict: is_dict, + is_array_of_map: is_array_of_map, + is_map_of_array: is_map_of_array, + dimension_count: dimension_count + } + + # If the value is a complex structure (Hash or Array), apply apply_unboxing_function + additional_properties[key] = if is_array || is_dict + apply_unboxing_function(value, unboxing_function, **args) else # Apply the unboxing function directly for simple values unboxing_function.call(value) end rescue StandardError - # Optionally log the error message or handle it as needed - # puts "Error processing key '#{key}': #{e.message}" # Ignore the exception and continue processing end additional_properties end - def self.apply_unboxing_function(obj, unboxing_function, as_array: false, as_dict: false) - if as_dict && obj.is_a?(Hash) - # If `obj` is a Hash and `as_dict` is true, apply the unboxing function to each value in the hash. - obj.transform_values { |v| apply_unboxing_function(v, unboxing_function, as_dict: true) } - elsif as_array && obj.is_a?(Array) - # If `obj` is an Array, apply the unboxing function to each element. - obj.map { |element| unboxing_function.call(element) } + def self.apply_unboxing_function(obj, unboxing_function, is_array: false, is_dict: false, is_array_of_map: false, + is_map_of_array: false, dimension_count: 1) + if is_dict + if is_map_of_array + # Handle case where the object is a map of arrays (Hash with array values) + obj.transform_values do |v| + apply_unboxing_function(v, unboxing_function, is_array: true, dimension_count: dimension_count) + end + else + # Handle regular Hash (map) case + obj.transform_values { |v| unboxing_function.call(v) } + end + elsif is_array + if is_array_of_map + # Handle case where the object is an array of maps (Array of Hashes) + obj.map do |element| + apply_unboxing_function(element, unboxing_function, is_dict: true, dimension_count: dimension_count) + end + elsif dimension_count > 1 + # Handle multi-dimensional array + obj.map do |element| + apply_unboxing_function(element, unboxing_function, is_array: true, + dimension_count: dimension_count - 1) + end + else + # Handle regular Array case + obj.map { |element| unboxing_function.call(element) } + end else - # Otherwise, apply the unboxing function directly to the object. + # Handle base case where the object is neither Array nor Hash unboxing_function.call(obj) end end diff --git a/test/test-apimatic-core/utilities/api_helper_test.rb b/test/test-apimatic-core/utilities/api_helper_test.rb index 2437d5c..52e68ae 100644 --- a/test/test-apimatic-core/utilities/api_helper_test.rb +++ b/test/test-apimatic-core/utilities/api_helper_test.rb @@ -710,17 +710,16 @@ def test_get_additional_properties_success { dictionary: { "a" => 1, "b" => 2 }, expected_result: { "a" => 1, "b" => 2 }, unboxing_func: Proc.new { |x| Integer(x) }}, { dictionary: { "a" => "1", "b" => "2" }, expected_result: { "a" => "1", "b" => "2" }, unboxing_func: Proc.new { |x| x.to_s }}, { dictionary: { "a" => "Test 1", "b" => "Test 2" }, expected_result: {}, unboxing_func: Proc.new { |x| Integer(x) }}, - { dictionary: { "a" => [1, 2], "b" => [3, 4] }, expected_result: { "a" => [1, 2], "b" => [3, 4] }, unboxing_func: Proc.new { |x| Integer(x) }, as_array: true}, - { dictionary: { "a" => { "x" => 1, "y" => 2 }, "b" => { "x" => 3, "y" => 4 } }, expected_result: { "a" => { "x" => 1, "y" => 2 }, "b" => { "x" => 3, "y" => 4 } }, unboxing_func: Proc.new { |x| Integer(x) }, as_array: false, as_dict: true} + { dictionary: { "a" => [1, 2], "b" => [3, 4] }, expected_result: { "a" => [1, 2], "b" => [3, 4] }, unboxing_func: Proc.new { |x| Integer(x) }, is_array: true}, + { dictionary: { "a" => { "x" => 1, "y" => 2 }, "b" => { "x" => 3, "y" => 4 } }, expected_result: { "a" => { "x" => 1, "y" => 2 }, "b" => { "x" => 3, "y" => 4 } }, unboxing_func: Proc.new { |x| Integer(x) }, is_array: false, is_dict: true} ] test_cases.each do |case_data| - actual_result = ApiHelper.get_additional_properties(case_data[:dictionary], case_data[:unboxing_func], as_array: case_data[:as_array], as_dict: case_data[:as_dict]) + actual_result = ApiHelper.get_additional_properties(case_data[:dictionary], case_data[:unboxing_func], is_array: case_data[:is_array], is_dict: case_data[:is_dict]) assert_equal(case_data[:expected_result], actual_result) end end - def test_get_additional_properties_exception test_cases = [ { dictionary: { "a" => nil }, unboxing_func: Proc.new { |x| Integer(x) } }, @@ -734,6 +733,51 @@ def test_get_additional_properties_exception end end -end - - + def test_apply_unboxing_function + test_cases = [ + # Test case 1: Simple object + { value: 5, unboxing_func: Proc.new { |x| x * 2 }, is_array: false, is_dict: false, + is_array_of_map: false, is_map_of_array: false, dimension_count: 0, expected: 10 }, + + # Test case 2: Array + { value: [1, 2, 3], unboxing_func: Proc.new { |x| x * 2 }, is_array: true, is_dict: false, + is_array_of_map: false, is_map_of_array: false, dimension_count: 0, expected: [2, 4, 6] }, + + # Test case 3: Dictionary + { value: { "a" => 1, "b" => 2 }, unboxing_func: Proc.new { |x| x * 2 }, is_array: false, + is_dict: true, is_array_of_map: false, is_map_of_array: false, dimension_count: 0, expected: { "a" => 2, "b" => 4 } }, + + # Test case 4: Array of maps + { value: [{ "a" => 1 }, { "b" => 2 }], unboxing_func: Proc.new { |x| x * 2 }, is_array: true, + is_dict: false, is_array_of_map: true, is_map_of_array: false, dimension_count: 0, expected: [{ "a" => 2 }, { "b" => 4 }] }, + + # Test case 5: Map of arrays + { value: { "a" => [1, 2], "b" => [3, 4] }, unboxing_func: Proc.new { |x| x * 2 }, is_array: false, + is_dict: true, is_array_of_map: false, is_map_of_array: true, dimension_count: 0, expected: { "a" => [2, 4], "b" => [6, 8] } }, + + # Test case 6: Multi-dimensional array + { value: [[1], [2, 3], [4]], unboxing_func: Proc.new { |x| x * 2 }, is_array: true, + is_dict: false, is_array_of_map: false, is_map_of_array: false, dimension_count: 2, expected: [[2], [4, 6], [8]] }, + + # Test case 7: Array of arrays + { value: [[1, 2], [3, 4]], unboxing_func: Proc.new { |x| x * 2 }, is_array: true, + is_dict: false, is_array_of_map: false, is_map_of_array: false, dimension_count: 2, expected: [[2, 4], [6, 8]] }, + + # Test case 8: Array of arrays of arrays + { value: [[[1, 2], [3, 4]], [[5, 6], [7, 8]]], unboxing_func: Proc.new { |x| x * 2 }, is_array: true, + is_dict: false, is_array_of_map: false, is_map_of_array: false, dimension_count: 3, expected: [[[2, 4], [6, 8]], [[10, 12], [14, 16]]] } + ] + + test_cases.each do |test_case| + result = ApiHelper.apply_unboxing_function(test_case[:value], + test_case[:unboxing_func], + is_array: test_case[:is_array], + is_dict: test_case[:is_dict], + is_array_of_map: test_case[:is_array_of_map], + is_map_of_array: test_case[:is_map_of_array], + dimension_count: test_case[:dimension_count]) + + assert_equal test_case[:expected], result + end + end +end \ No newline at end of file diff --git a/test/test-helper/models/base_with_additional_properties.rb b/test/test-helper/models/base_with_additional_properties.rb new file mode 100644 index 0000000..1cb6143 --- /dev/null +++ b/test/test-helper/models/base_with_additional_properties.rb @@ -0,0 +1,50 @@ +# lib/models/base_with_additional_properties.rb +module TestComponent + class BaseWithAdditionalProperties < BaseModel + SKIP = Object.new + private_constant :SKIP + + attr_accessor :email + attr_reader :additional_properties + + def self.names + @_hash ||= {} + @_hash['email'] = 'email' + @_hash + end + + # An array for optional fields + def self.optionals + [] + end + + # An array for nullable fields + def self.nullables + [] + end + + def initialize(email = nil, additional_properties = nil) + @email = email + @additional_properties = additional_properties || {} + end + + # Common from_hash logic for all models with additional properties + def self.from_hash(hash) + return nil unless hash + + email = hash['email'] + new_hash = hash.reject { |key, _| self.names.key?(key) } + + additional_properties = get_additional_properties_from_hash(new_hash) + + new(self, email, additional_properties) + end + + private + + def self.get_additional_properties_from_hash(new_hash) + # This is a stub method and should be overridden in each subclass. + raise NotImplementedError, 'Subclasses must define this method' + end + end +end diff --git a/test/test-helper/models/model_with_additional_properties_of_model_array_type.rb b/test/test-helper/models/model_with_additional_properties_of_model_array_type.rb index 238f069..f69bf6c 100644 --- a/test/test-helper/models/model_with_additional_properties_of_model_array_type.rb +++ b/test/test-helper/models/model_with_additional_properties_of_model_array_type.rb @@ -1,53 +1,17 @@ -require_relative '../models/base_model' + +require_relative '../models/base_with_additional_properties' require_relative '../models/evening' module TestComponent - class ModelWithAdditionalPropertiesOfModelArrayType < BaseModel - SKIP = Object.new - private_constant :SKIP - - # @return [String] - attr_accessor :email - - # A mapping from model property names to API property names. - def self.names - @_hash = {} if @_hash.nil? - @_hash['email'] = 'email' - @_hash - end - - # An array for optional fields - def self.optionals - [] - end - - # An array for nullable fields - def self.nullables - [] - end - - def initialize(email = nil, additional_properties = nil) - additional_properties = {} if additional_properties.nil? - - @email = email - @additional_properties = additional_properties - end - - # Creates an instance of the object from a hash. - def self.from_hash(hash) - return nil unless hash - - # Extract variables from the hash. - email = hash.key?('email') ? hash['email'] : nil - - # Create a new hash for additional properties, removing known properties. - new_hash = hash.reject { |key, _| self.names.key?(key) } - - additional_properties = CoreLibrary::APIHelper.get_additional_properties( - new_hash, Proc.new { |item| Evening.from_dictionary(item) }, as_array: true) - - # Create object from extracted values. - ModelWithAdditionalPropertiesOfModelArrayType.new(email, additional_properties) - end + class ModelWithAdditionalPropertiesOfModelArrayType < BaseWithAdditionalProperties + private + + def self.get_additional_properties_from_hash(new_hash) + CoreLibrary::APIHelper.get_additional_properties( + new_hash, + Proc.new { |item| Evening.from_dictionary(item) }, + as_array: true + ) + end end -end \ No newline at end of file +end diff --git a/test/test-helper/models/model_with_additional_properties_of_model_dict_type.rb b/test/test-helper/models/model_with_additional_properties_of_model_dict_type.rb index 0eb1c52..efbd6fb 100644 --- a/test/test-helper/models/model_with_additional_properties_of_model_dict_type.rb +++ b/test/test-helper/models/model_with_additional_properties_of_model_dict_type.rb @@ -1,53 +1,17 @@ -require_relative '../models/base_model' +# lib/models/model_with_additional_properties_of_model_dict_type.rb +require_relative '../models/base_with_additional_properties' require_relative '../models/evening' module TestComponent - class ModelWithAdditionalPropertiesOfModelDictType < BaseModel - SKIP = Object.new - private_constant :SKIP - - # @return [String] - attr_accessor :email - - # A mapping from model property names to API property names. - def self.names - @_hash = {} if @_hash.nil? - @_hash['email'] = 'email' - @_hash - end - - # An array for optional fields - def self.optionals - [] - end - - # An array for nullable fields - def self.nullables - [] - end - - def initialize(email = nil, additional_properties = nil) - additional_properties = {} if additional_properties.nil? - - @email = email - @additional_properties = additional_properties - end - - # Creates an instance of the object from a hash. - def self.from_hash(hash) - return nil unless hash - - # Extract variables from the hash. - email = hash.key?('email') ? hash['email'] : nil - - # Create a new hash for additional properties, removing known properties. - new_hash = hash.reject { |key, _| self.names.key?(key) } - - additional_properties = CoreLibrary::APIHelper.get_additional_properties( - new_hash, Proc.new { |item| Evening.from_dictionary(item) }, as_dict: true) - - # Create object from extracted values. - ModelWithAdditionalPropertiesOfModelDictType.new(email, additional_properties) + class ModelWithAdditionalPropertiesOfModelDictType < BaseWithAdditionalProperties + private + + def self.get_additional_properties_from_hash(new_hash) + CoreLibrary::APIHelper.get_additional_properties( + new_hash, + Proc.new { |item| Evening.from_dictionary(item) }, + as_dict: true + ) end end -end \ No newline at end of file +end diff --git a/test/test-helper/models/model_with_additional_properties_of_model_type.rb b/test/test-helper/models/model_with_additional_properties_of_model_type.rb index b8fd7c6..e01471a 100644 --- a/test/test-helper/models/model_with_additional_properties_of_model_type.rb +++ b/test/test-helper/models/model_with_additional_properties_of_model_type.rb @@ -1,53 +1,15 @@ -require_relative '../models/base_model' +require_relative '../models/base_with_additional_properties' require_relative '../models/evening' module TestComponent - class ModelWithAdditionalPropertiesOfModelType < BaseModel - SKIP = Object.new - private_constant :SKIP + class ModelWithAdditionalPropertiesOfModelType < BaseWithAdditionalProperties + private - # @return [String] - attr_accessor :email - - # A mapping from model property names to API property names. - def self.names - @_hash = {} if @_hash.nil? - @_hash['email'] = 'email' - @_hash - end - - # An array for optional fields - def self.optionals - [] - end - - # An array for nullable fields - def self.nullables - [] - end - - def initialize(email = nil, additional_properties = nil) - additional_properties = {} if additional_properties.nil? - - @email = email - @additional_properties = additional_properties - end - - # Creates an instance of the object from a hash. - def self.from_hash(hash) - return nil unless hash - - # Extract variables from the hash. - email = hash.key?('email') ? hash['email'] : nil - - # Create a new hash for additional properties, removing known properties. - new_hash = hash.reject { |key, _| self.names.key?(key) } - - additional_properties = CoreLibrary::APIHelper.get_additional_properties( - new_hash, Proc.new { |item| Evening.from_dictionary(item) }) - - # Create object from extracted values. - ModelWithAdditionalPropertiesOfModelType.new(email, additional_properties) + def self.get_additional_properties_from_hash(new_hash) + CoreLibrary::APIHelper.get_additional_properties( + new_hash, + Proc.new { |item| Evening.from_dictionary(item) } + ) end end -end \ No newline at end of file +end diff --git a/test/test-helper/models/model_with_additional_properties_of_primitive_array_type.rb b/test/test-helper/models/model_with_additional_properties_of_primitive_array_type.rb index e38d916..b90333f 100644 --- a/test/test-helper/models/model_with_additional_properties_of_primitive_array_type.rb +++ b/test/test-helper/models/model_with_additional_properties_of_primitive_array_type.rb @@ -1,52 +1,15 @@ -require_relative '../models/base_model' +require_relative '../models/base_with_additional_properties' module TestComponent - class ModelWithAdditionalPropertiesOfPrimitiveArrayType < BaseModel - SKIP = Object.new - private_constant :SKIP + class ModelWithAdditionalPropertiesOfPrimitiveArrayType < BaseWithAdditionalProperties + private - # @return [String] - attr_accessor :email - - # A mapping from model property names to API property names. - def self.names - @_hash = {} if @_hash.nil? - @_hash['email'] = 'email' - @_hash - end - - # An array for optional fields - def self.optionals - [] - end - - # An array for nullable fields - def self.nullables - [] - end - - def initialize(email = nil, additional_properties = nil) - additional_properties = {} if additional_properties.nil? - - @email = email - @additional_properties = additional_properties - end - - # Creates an instance of the object from a hash. - def self.from_hash(hash) - return nil unless hash - - # Extract variables from the hash. - email = hash.key?('email') ? hash['email'] : nil - - # Create a new hash for additional properties, removing known properties. - new_hash = hash.reject { |key, _| self.names.key?(key) } - - additional_properties = CoreLibrary::APIHelper.get_additional_properties( - new_hash, Proc.new { |x| Integer(x) }, as_array: true) - - # Create object from extracted values. - ModelWithAdditionalPropertiesOfPrimitiveArrayType.new(email, additional_properties) + def self.get_additional_properties_from_hash(new_hash) + CoreLibrary::APIHelper.get_additional_properties( + new_hash, + Proc.new { |x| Integer(x) }, + as_array: true + ) end end -end \ No newline at end of file +end diff --git a/test/test-helper/models/model_with_additional_properties_of_primitive_dict_type.rb b/test/test-helper/models/model_with_additional_properties_of_primitive_dict_type.rb index 19876e5..5c57ac1 100644 --- a/test/test-helper/models/model_with_additional_properties_of_primitive_dict_type.rb +++ b/test/test-helper/models/model_with_additional_properties_of_primitive_dict_type.rb @@ -1,52 +1,16 @@ -require_relative '../models/base_model' +require_relative '../models/base_with_additional_properties' module TestComponent - class ModelWithAdditionalPropertiesOfPrimitiveDictType < BaseModel - SKIP = Object.new - private_constant :SKIP - - # @return [String] - attr_accessor :email - - # A mapping from model property names to API property names. - def self.names - @_hash = {} if @_hash.nil? - @_hash['email'] = 'email' - @_hash - end - - # An array for optional fields - def self.optionals - [] - end - - # An array for nullable fields - def self.nullables - [] - end - - def initialize(email = nil, additional_properties = nil) - additional_properties = {} if additional_properties.nil? - - @email = email - @additional_properties = additional_properties - end - - # Creates an instance of the object from a hash. - def self.from_hash(hash) - return nil unless hash - - # Extract variables from the hash. - email = hash.key?('email') ? hash['email'] : nil - - # Create a new hash for additional properties, removing known properties. - new_hash = hash.reject { |key, _| self.names.key?(key) } - - additional_properties = CoreLibrary::APIHelper.get_additional_properties( - new_hash, Proc.new { |x| Integer(x) }, as_array: false, as_dict: true) - - # Create object from extracted values. - ModelWithAdditionalPropertiesOfPrimitiveDictType.new(email, additional_properties) + class ModelWithAdditionalPropertiesOfPrimitiveDictType < BaseWithAdditionalProperties + private + + def self.get_additional_properties_from_hash(new_hash) + CoreLibrary::APIHelper.get_additional_properties( + new_hash, + Proc.new { |x| Integer(x) }, + as_array: false, + as_dict: true + ) end end -end \ No newline at end of file +end diff --git a/test/test-helper/models/model_with_additional_properties_of_primitive_type.rb b/test/test-helper/models/model_with_additional_properties_of_primitive_type.rb index 402235f..ff3082b 100644 --- a/test/test-helper/models/model_with_additional_properties_of_primitive_type.rb +++ b/test/test-helper/models/model_with_additional_properties_of_primitive_type.rb @@ -1,52 +1,15 @@ -require_relative '../models/base_model' +# lib/models/model_with_additional_properties_of_primitive_type.rb +require_relative '../models/base_with_additional_properties' module TestComponent - class ModelWithAdditionalPropertiesOfPrimitiveType < BaseModel - SKIP = Object.new - private_constant :SKIP - - # @return [String] - attr_accessor :email - - # A mapping from model property names to API property names. - def self.names - @_hash = {} if @_hash.nil? - @_hash['email'] = 'email' - @_hash - end - - # An array for optional fields - def self.optionals - [] - end - - # An array for nullable fields - def self.nullables - [] - end - - def initialize(email = nil, additional_properties = nil) - additional_properties = {} if additional_properties.nil? - - @email = email - @additional_properties = additional_properties - end - - # Creates an instance of the object from a hash. - def self.from_hash(hash) - return nil unless hash - - # Extract variables from the hash. - email = hash.key?('email') ? hash['email'] : nil - - # Create a new hash for additional properties, removing known properties. - new_hash = hash.reject { |key, _| self.names.key?(key) } - - additional_properties = APIHelper.get_additional_properties( - new_hash, Proc.new { |x| Integer(x) }) - - # Create object from extracted values. - ModelWithAdditionalPropertiesOfPrimitiveType.new(email, additional_properties) + class ModelWithAdditionalPropertiesOfPrimitiveType < BaseWithAdditionalProperties + private + + def self.get_additional_properties_from_hash(new_hash) + CoreLibrary::APIHelper.get_additional_properties( + new_hash, + Proc.new { |x| Integer(x) } + ) end end end \ No newline at end of file diff --git a/test/test-helper/models/model_with_additional_properties_of_type_combinator_primitive_type.rb b/test/test-helper/models/model_with_additional_properties_of_type_combinator_primitive_type.rb index 19b8615..184db4f 100644 --- a/test/test-helper/models/model_with_additional_properties_of_type_combinator_primitive_type.rb +++ b/test/test-helper/models/model_with_additional_properties_of_type_combinator_primitive_type.rb @@ -1,54 +1,14 @@ -require_relative '../models/base_model' -require_relative '../models/evening' +require_relative '../models/base_with_additional_properties' module TestComponent - class ModelWithAdditionalPropertiesOfTypeCombinatorPrimitiveType < BaseModel - SKIP = Object.new - private_constant :SKIP + class ModelWithAdditionalPropertiesOfTypeCombinatorPrimitiveType < BaseWithAdditionalProperties + private - # @return [String] - attr_accessor :email - - # A mapping from model property names to API property names. - def self.names - @_hash = {} if @_hash.nil? - @_hash['email'] = 'email' - @_hash - end - - # An array for optional fields - def self.optionals - [] - end - - # An array for nullable fields - def self.nullables - [] - end - - def initialize(email = nil, additional_properties = nil) - additional_properties = {} if additional_properties.nil? - - @email = email - @additional_properties = additional_properties - end - - # Creates an instance of the object from a hash. - def self.from_hash(hash) - return nil unless hash - - # Extract variables from the hash. - email = hash.key?('email') ? hash['email'] : nil - - # Create a new hash for additional properties, removing known properties. - new_hash = hash.reject { |key, _| self.names.key?(key) } - - additional_properties = CoreLibrary::APIHelper.get_additional_properties( - new_hash, Proc.new { |x| CoreLibrary::ApiHelper.deserialize_union_type(UnionTypeLookUp.get('scalarModelAnyOfRequired'), - x)}) - - # Create object from extracted values. - ModelWithAdditionalPropertiesOfTypeCombinatorPrimitiveType.new(email, additional_properties) + def self.get_additional_properties_from_hash(new_hash) + CoreLibrary::APIHelper.get_additional_properties( + new_hash, + Proc.new { |x| CoreLibrary::ApiHelper.deserialize_union_type(UnionTypeLookUp.get('scalarModelAnyOfRequired'), x) } + ) end end -end \ No newline at end of file +end From 0d6f198effed819651e0344a0d70ad30cc6b9615 Mon Sep 17 00:00:00 2001 From: MaryamAdnan3 Date: Mon, 11 Nov 2024 16:00:47 +0500 Subject: [PATCH 7/8] fixed 4 quality issues reported --- test/test-apimatic-core/test_helper.rb | 2 ++ .../utilities/api_helper_test.rb | 29 ++++++++++--------- test/test-helper/mock_helper.rb | 18 +++++++----- .../models/base_with_additional_properties.rb | 5 ++-- 4 files changed, 31 insertions(+), 23 deletions(-) diff --git a/test/test-apimatic-core/test_helper.rb b/test/test-apimatic-core/test_helper.rb index 20dd30e..783f1d2 100644 --- a/test/test-apimatic-core/test_helper.rb +++ b/test/test-apimatic-core/test_helper.rb @@ -11,3 +11,5 @@ # test constants TEST_TOKEN = 'MyDuMmYtOkEn'.freeze JSON_CONTENT_TYPE = 'application/json'.freeze +FORM_PARAM_KEY = 'form_param'.freeze +TEST_EMAIL = 'test@gmail.com' \ No newline at end of file diff --git a/test/test-apimatic-core/utilities/api_helper_test.rb b/test/test-apimatic-core/utilities/api_helper_test.rb index 52e68ae..0ce819c 100644 --- a/test/test-apimatic-core/utilities/api_helper_test.rb +++ b/test/test-apimatic-core/utilities/api_helper_test.rb @@ -5,6 +5,7 @@ require_relative '../../test-helper/models/person' require_relative '../../test-helper/models/morning' require_relative '../../../lib/apimatic-core/utilities/file_helper' +require_relative '../test_helper' require 'faraday' class ApiHelperTest < Minitest::Test @@ -313,29 +314,31 @@ def test_form_encode end - def test_form_encoding_with_additional_props - key = "form_param" + def test_form_encode_with_additional_properties + key = FORM_PARAM_KEY test_cases = [ [TestComponent::MockHelper.get_model_with_additional_properties_of_primitive_type_success, - { 'form_param[email]' => 'test@gmail.com', 'form_param[prop]' => 20 }], + { "#{FORM_PARAM_KEY}[email]" => "#{TEST_EMAIL}", "#{FORM_PARAM_KEY}[prop]" => 20 }], [TestComponent::MockHelper.get_model_with_additional_properties_of_primitive_array_type, - { 'form_param[email]' => 'test@gmail.com', 'form_param[prop][0]' => 20, 'form_param[prop][1]' => 30 }], + { "#{FORM_PARAM_KEY}[email]" => "#{TEST_EMAIL}", "#{FORM_PARAM_KEY}[prop][0]" => 20, "#{FORM_PARAM_KEY}[prop][1]" => 30 }], [TestComponent::MockHelper.get_model_with_additional_properties_of_primitive_dict_type, - { 'form_param[email]' => 'test@gmail.com', 'form_param[prop][inner prop 1]' => 20, 'form_param[prop][inner prop 2]' => 30 }], + { "#{FORM_PARAM_KEY}[email]" => "#{TEST_EMAIL}", "#{FORM_PARAM_KEY}[prop][inner prop 1]" => 20, "#{FORM_PARAM_KEY}[prop][inner prop 2]" => 30 }], [TestComponent::MockHelper.get_model_with_additional_properties_of_model_type, - { 'form_param[email]' => 'test@gmail.com', "form_param[prop1][starts_at]"=>"8:00", "form_param[prop1][ends_at]"=>"10:00", "form_param[prop1][offer_dinner]"=> true, "form_param[prop1][session_type]"=>"Evening"}], + { "#{FORM_PARAM_KEY}[email]" => "#{TEST_EMAIL}", "#{FORM_PARAM_KEY}[prop1][starts_at]" => "8:00", "#{FORM_PARAM_KEY}[prop1][ends_at]" => "10:00", + "#{FORM_PARAM_KEY}[prop1][offer_dinner]" => true, "#{FORM_PARAM_KEY}[prop1][session_type]" => "Evening" }], [TestComponent::MockHelper.get_model_with_additional_properties_of_model_array_type, - { 'form_param[email]' => 'test@gmail.com', - "form_param[prop1][0][starts_at]"=>"8:00", "form_param[prop1][0][ends_at]"=>"10:00", "form_param[prop1][0][offer_dinner]"=>true, "form_param[prop1][0][session_type]"=>"Evening", - "form_param[prop1][1][starts_at]"=>"8:00", "form_param[prop1][1][ends_at]"=>"10:00", "form_param[prop1][1][offer_dinner]"=>true, "form_param[prop1][1][session_type]"=>"Evening"}], + { "#{FORM_PARAM_KEY}[email]" => "#{TEST_EMAIL}", + "#{FORM_PARAM_KEY}[prop1][0][starts_at]" => "8:00", "#{FORM_PARAM_KEY}[prop1][0][ends_at]" => "10:00", "#{FORM_PARAM_KEY}[prop1][0][offer_dinner]" => true, "#{FORM_PARAM_KEY}[prop1][0][session_type]" => "Evening", + "#{FORM_PARAM_KEY}[prop1][1][starts_at]" => "8:00", "#{FORM_PARAM_KEY}[prop1][1][ends_at]" => "10:00", "#{FORM_PARAM_KEY}[prop1][1][offer_dinner]" => true, "#{FORM_PARAM_KEY}[prop1][1][session_type]" => "Evening" }], [TestComponent::MockHelper.get_model_with_additional_properties_of_model_dict_type, - {"form_param[email]"=>"test@gmail.com", - "form_param[prop1][inner_prop1][starts_at]"=>"8:00", "form_param[prop1][inner_prop1][ends_at]"=>"10:00", "form_param[prop1][inner_prop1][offer_dinner]"=>true, "form_param[prop1][inner_prop1][session_type]"=>"Evening", - "form_param[prop1][inner_prop2][starts_at]"=>"8:00", "form_param[prop1][inner_prop2][ends_at]"=>"10:00", "form_param[prop1][inner_prop2][offer_dinner]"=>true, "form_param[prop1][inner_prop2][session_type]"=>"Evening"}], + { "#{FORM_PARAM_KEY}[email]" => "#{TEST_EMAIL}", + "#{FORM_PARAM_KEY}[prop1][inner_prop1][starts_at]" => "8:00", "#{FORM_PARAM_KEY}[prop1][inner_prop1][ends_at]" => "10:00", "#{FORM_PARAM_KEY}[prop1][inner_prop1][offer_dinner]" => true, "#{FORM_PARAM_KEY}[prop1][inner_prop1][session_type]" => "Evening", + "#{FORM_PARAM_KEY}[prop1][inner_prop2][starts_at]" => "8:00", "#{FORM_PARAM_KEY}[prop1][inner_prop2][ends_at]" => "10:00", "#{FORM_PARAM_KEY}[prop1][inner_prop2][offer_dinner]" => true, "#{FORM_PARAM_KEY}[prop1][inner_prop2][session_type]" => "Evening" }], [TestComponent::MockHelper.get_model_with_additional_properties_of_type_combinator_primitive_type, - { 'form_param[email]' => 'test@gmail.com', 'form_param[prop]' => 10.55 }] + { "#{FORM_PARAM_KEY}[email]" => "#{TEST_EMAIL}", "#{FORM_PARAM_KEY}[prop]" => 10.55 }] ] + # Iterate through each test case test_cases.each do |input_value, expected_form_params| assert_equal(ApiHelper.form_encode(input_value, key, formatting: ArraySerializationFormat::INDEXED), expected_form_params) diff --git a/test/test-helper/mock_helper.rb b/test/test-helper/mock_helper.rb index df6b897..6b58368 100644 --- a/test/test-helper/mock_helper.rb +++ b/test/test-helper/mock_helper.rb @@ -58,6 +58,8 @@ class MockHelper } }.freeze + TEST_EMAIL = 'test@gmail.com' + def self.test_token "KJGHGHFDFGH6757FGDFH67FTDFH567FGDHGDGFDC" end @@ -201,42 +203,42 @@ def self.get_attributes_elements_model_with_datetime end def self.get_model_with_additional_properties_of_primitive_type - model_with_additional_properties_of_primitive_type = ModelWithAdditionalPropertiesOfPrimitiveType.new("test@gmail.com", { 'email' => 10.55 }) + model_with_additional_properties_of_primitive_type = ModelWithAdditionalPropertiesOfPrimitiveType.new("#{TEST_EMAIL}", { 'email' => 10.55 }) return model_with_additional_properties_of_primitive_type end def self.get_model_with_additional_properties_of_primitive_type_success - model_with_additional_properties_of_primitive_type = ModelWithAdditionalPropertiesOfPrimitiveType.new("test@gmail.com", { 'prop' => 20 }) + model_with_additional_properties_of_primitive_type = ModelWithAdditionalPropertiesOfPrimitiveType.new("#{TEST_EMAIL}", { 'prop' => 20 }) return model_with_additional_properties_of_primitive_type end def self.get_model_with_additional_properties_of_primitive_array_type - model_with_additional_properties_of_primitive_array_type = ModelWithAdditionalPropertiesOfPrimitiveArrayType.new('test@gmail.com', { 'prop' => [20, 30] }) + model_with_additional_properties_of_primitive_array_type = ModelWithAdditionalPropertiesOfPrimitiveArrayType.new("#{TEST_EMAIL}", { 'prop' => [20, 30] }) return model_with_additional_properties_of_primitive_array_type end def self.get_model_with_additional_properties_of_primitive_dict_type - model_with_additional_properties_of_primitive_dict_type = ModelWithAdditionalPropertiesOfPrimitiveDictType.new("test@gmail.com", { 'prop' => { 'inner prop 1' => 20, 'inner prop 2' => 30 } }) + model_with_additional_properties_of_primitive_dict_type = ModelWithAdditionalPropertiesOfPrimitiveDictType.new("#{TEST_EMAIL}", { 'prop' => { 'inner prop 1' => 20, 'inner prop 2' => 30 } }) return model_with_additional_properties_of_primitive_dict_type end def self.get_model_with_additional_properties_of_model_type - model_with_additional_properties_of_model_type = ModelWithAdditionalPropertiesOfModelType.new("test@gmail.com", "prop1": {"starts_at": "8:00", "ends_at": "10:00", "offer_dinner": true, "session_type": "Evening"}) + model_with_additional_properties_of_model_type = ModelWithAdditionalPropertiesOfModelType.new("#{TEST_EMAIL}", "prop1": {"starts_at": "8:00", "ends_at": "10:00", "offer_dinner": true, "session_type": "Evening"}) return model_with_additional_properties_of_model_type end def self.get_model_with_additional_properties_of_model_array_type - model_with_additional_properties_of_model_array_type = ModelWithAdditionalPropertiesOfModelArrayType.new("test@gmail.com", "prop1": [{"starts_at": "8:00", "ends_at": "10:00", "offer_dinner": true, "session_type": "Evening"}, {"starts_at": "8:00", "ends_at": "10:00", "offer_dinner": true, "session_type": "Evening"}]) + model_with_additional_properties_of_model_array_type = ModelWithAdditionalPropertiesOfModelArrayType.new("#{TEST_EMAIL}", "prop1": [{"starts_at": "8:00", "ends_at": "10:00", "offer_dinner": true, "session_type": "Evening"}, {"starts_at": "8:00", "ends_at": "10:00", "offer_dinner": true, "session_type": "Evening"}]) return model_with_additional_properties_of_model_array_type end def self.get_model_with_additional_properties_of_model_dict_type - model_with_additional_properties_of_model_dict_type = ModelWithAdditionalPropertiesOfModelDictType.new("test@gmail.com", "prop1": {"inner_prop1": {"starts_at": "8:00", "ends_at": "10:00", "offer_dinner": true, "session_type": "Evening"}, "inner_prop2": {"starts_at": "8:00", "ends_at": "10:00", "offer_dinner": true, "session_type": "Evening"}}) + model_with_additional_properties_of_model_dict_type = ModelWithAdditionalPropertiesOfModelDictType.new("#{TEST_EMAIL}", "prop1": {"inner_prop1": {"starts_at": "8:00", "ends_at": "10:00", "offer_dinner": true, "session_type": "Evening"}, "inner_prop2": {"starts_at": "8:00", "ends_at": "10:00", "offer_dinner": true, "session_type": "Evening"}}) return model_with_additional_properties_of_model_dict_type end def self.get_model_with_additional_properties_of_type_combinator_primitive_type - model_with_additional_properties_of_type_combinator_primitive_type = ModelWithAdditionalPropertiesOfTypeCombinatorPrimitiveType.new("test@gmail.com",{ 'prop' => 10.55 }) + model_with_additional_properties_of_type_combinator_primitive_type = ModelWithAdditionalPropertiesOfTypeCombinatorPrimitiveType.new("#{TEST_EMAIL}",{ 'prop' => 10.55 }) return model_with_additional_properties_of_type_combinator_primitive_type end end diff --git a/test/test-helper/models/base_with_additional_properties.rb b/test/test-helper/models/base_with_additional_properties.rb index 1cb6143..1270089 100644 --- a/test/test-helper/models/base_with_additional_properties.rb +++ b/test/test-helper/models/base_with_additional_properties.rb @@ -41,10 +41,11 @@ def self.from_hash(hash) end private - + # rubocop:disable Lint/UnusedMethodArgument def self.get_additional_properties_from_hash(new_hash) - # This is a stub method and should be overridden in each subclass. + # Placeholder to be implemented by subclasses raise NotImplementedError, 'Subclasses must define this method' end + # rubocop:enable Lint/UnusedMethodArgument end end From 53dfb31a2fd26d2c87888a45a2d561f5f6baf431 Mon Sep 17 00:00:00 2001 From: MaryamAdnan3 Date: Thu, 28 Nov 2024 11:14:38 +0500 Subject: [PATCH 8/8] Refactoring and addition of few new cases in json_deserialize --- .../utilities/api_helper_test.rb | 57 ++++++++++--------- .../models/base_with_additional_properties.rb | 6 +- ...ditional_properties_of_model_array_type.rb | 6 +- ...dditional_properties_of_model_dict_type.rb | 6 +- ...ith_additional_properties_of_model_type.rb | 4 +- ...onal_properties_of_primitive_array_type.rb | 4 +- ...ional_properties_of_primitive_dict_type.rb | 6 +- ...additional_properties_of_primitive_type.rb | 2 +- ...rties_of_type_combinator_primitive_type.rb | 5 +- test/test-helper/models/union_type_lookup.rb | 7 ++- 10 files changed, 52 insertions(+), 51 deletions(-) diff --git a/test/test-apimatic-core/utilities/api_helper_test.rb b/test/test-apimatic-core/utilities/api_helper_test.rb index 0ce819c..8792e38 100644 --- a/test/test-apimatic-core/utilities/api_helper_test.rb +++ b/test/test-apimatic-core/utilities/api_helper_test.rb @@ -575,52 +575,53 @@ def test_valid_type_model_array_of_map is_model_hash: true, is_inner_model_hash: true) end - def json_deserialize + def test_json_deserialize test_cases = [ - ['{"email": "test", "prop1": 1, "prop2": 2, "prop3": "invalid type"}', + ['{"email":"test","prop1":1,"prop2":2,"prop3":"invalid type"}', TestComponent::ModelWithAdditionalPropertiesOfPrimitiveType, false, - '{"email": "test", "prop1": 1, "prop2": 2}'], + '{"email":"test","prop1":1,"prop2":2}'], - ['{"email": "test", "prop1": [1, 2, 3], "prop2": [1, 2, 3], "prop3": "invalid type"}', + ['{"email":"test","prop1":[1,2,3],"prop2":[1,2,3],"prop3":"invalid type"}', TestComponent::ModelWithAdditionalPropertiesOfPrimitiveArrayType, false, - '{"email": "test", "prop1": [1, 2, 3], "prop2": [1, 2, 3]}'], + '{"email":"test","prop1":[1,2,3],"prop2":[1,2,3]}'], - ['{"email": "test", "prop1": {"inner_prop1": 1, "inner_prop2": 2}, "prop2": {"inner_prop1": 1, "inner_prop2": 2}, "prop3": "invalid type"}', + ['{"email":"test","prop1":{"inner_prop1":1,"inner_prop2":2},"prop2":{"inner_prop1":1,"inner_prop2":2},"prop3":"invalid type"}', TestComponent::ModelWithAdditionalPropertiesOfPrimitiveDictType, false, - '{"email": "test", "prop1": {"inner_prop1": 1, "inner_prop2": 2}, "prop2": {"inner_prop1": 1, "inner_prop2": 2}}'], + '{"email":"test","prop1":{"inner_prop1":1,"inner_prop2":2},"prop2":{"inner_prop1":1,"inner_prop2":2}}'], - ['{"email": "test", "prop1": {"id": 1, "weight": 50, "type": "Lion"}, "prop3": "invalid type"}', + ['{"email":"test","prop1":{"startsAt":"15:30","endsAt":"20:30","offerDinner":false,"sessionType":"Evening"},"prop3":"invalid type"}', TestComponent::ModelWithAdditionalPropertiesOfModelType, false, - '{"email": "test", "prop1": {"id": 1, "weight": 50, "type": "Lion"}}'], + '{"email":"test","prop1":{"startsAt":"15:30","endsAt":"20:30","offerDinner":false,"sessionType":"Evening"}}'], - ['{"email": "test", "prop": [{"id": 1, "weight": 50, "type": "Lion"}, {"id": 2, "weight": 100, "type": "Lion"}]}', + ['{"email":"test","prop":[{"startsAt":"15:30","endsAt":"20:30","offerDinner":false,"sessionType":"Evening"},{"startsAt":"15:30","endsAt":"20:30","offerDinner":false,"sessionType":"Evening"}]}', TestComponent::ModelWithAdditionalPropertiesOfModelArrayType, false, - '{"email": "test", "prop": [{"id": 1, "weight": 50, "type": "Lion"}, {"id": 2, "weight": 100, "type": "Lion"}]}'], + '{"email":"test","prop":[{"startsAt":"15:30","endsAt":"20:30","offerDinner":false,"sessionType":"Evening"},{"startsAt":"15:30","endsAt":"20:30","offerDinner":false,"sessionType":"Evening"}]}'], - ['{"email": "test", "prop": {"inner prop 1": {"id": 1, "weight": 50, "type": "Lion"}, "inner prop 2": {"id": 2, "weight": 100, "type": "Lion"}}}', + ['{"email":"test","prop":{"inner prop 1":{"startsAt":"15:30","endsAt":"20:30","offerDinner":false,"sessionType":"Evening"},"inner prop 2":{"startsAt":"15:30","endsAt":"20:30","offerDinner":false,"sessionType":"Evening"}}}', TestComponent::ModelWithAdditionalPropertiesOfModelDictType, false, - '{"email": "test", "prop": {"inner prop 1": {"id": 1, "weight": 50, "type": "Lion"}, "inner prop 2": {"id": 2, "weight": 100, "type": "Lion"}}}'], - - ['{"email": "test", "prop": true}', - TestComponent::ModelWithAdditionalPropertiesOfTypeCombinatorPrimitive, false, - '{"email": "test", "prop": true}'], - - ['{"email": "test", "prop": 100.65}', - TestComponent::ModelWithAdditionalPropertiesOfTypeCombinatorPrimitive, false, - '{"email": "test", "prop": 100.65}'], - - ['{"email": "test", "prop": "100.65"}', - TestComponent::ModelWithAdditionalPropertiesOfTypeCombinatorPrimitive, false, - '{"email": "test"}'] + '{"email":"test","prop":{"inner prop 1":{"startsAt":"15:30","endsAt":"20:30","offerDinner":false,"sessionType":"Evening"},"inner prop 2":{"startsAt":"15:30","endsAt":"20:30","offerDinner":false,"sessionType":"Evening"}}}'], + + ['{"email":"test","prop":{"startsAt":"15:30","endsAt":"20:30","offerDinner":false,"sessionType":"Evening"}}', + TestComponent::ModelWithAdditionalPropertiesOfTypeCombinatorPrimitiveType, false, + '{"email":"test","prop":{"startsAt":"15:30","endsAt":"20:30","offerDinner":false,"sessionType":"Evening"}}'], + ['{"email":"test","prop":"100.65"}', + TestComponent::ModelWithAdditionalPropertiesOfTypeCombinatorPrimitiveType, false, + '{"email":"test","prop":"100.65"}'], + ['{"email":"test","prop":"some string"}', + TestComponent::ModelWithAdditionalPropertiesOfTypeCombinatorPrimitiveType, false, + '{"email":"test","prop":"some string"}'], + ['{"email":"test","prop":100.65}', + TestComponent::ModelWithAdditionalPropertiesOfTypeCombinatorPrimitiveType, false, + '{"email":"test"}'], ] # Iterate through each test case test_cases.each do |input_json_value, model_class, as_dict, expected_value| deserialized_value = model_class.from_hash( - APIHelper.json_deserialize(input_json_value, as_dict) + ApiHelper.json_deserialize(input_json_value, as_dict) ) - serialized_value = APIHelper.json_serialize(deserialized_value) + serialized_value = ApiHelper.json_serialize(deserialized_value) # Assert that the serialized value matches the expected value assert_equal expected_value, serialized_value @@ -706,7 +707,7 @@ def test_deserialize_union_type ] assert_equal(expected, actual, 'Actual did not match the expected.') end - + def test_get_additional_properties_success test_cases = [ { dictionary: {}, expected_result: {}, unboxing_func: Proc.new { |x| Integer(x) }}, diff --git a/test/test-helper/models/base_with_additional_properties.rb b/test/test-helper/models/base_with_additional_properties.rb index 1270089..302111a 100644 --- a/test/test-helper/models/base_with_additional_properties.rb +++ b/test/test-helper/models/base_with_additional_properties.rb @@ -34,10 +34,8 @@ def self.from_hash(hash) email = hash['email'] new_hash = hash.reject { |key, _| self.names.key?(key) } - - additional_properties = get_additional_properties_from_hash(new_hash) - - new(self, email, additional_properties) + additional_properties = self.get_additional_properties_from_hash(new_hash) + new(email, additional_properties) end private diff --git a/test/test-helper/models/model_with_additional_properties_of_model_array_type.rb b/test/test-helper/models/model_with_additional_properties_of_model_array_type.rb index f69bf6c..37adb60 100644 --- a/test/test-helper/models/model_with_additional_properties_of_model_array_type.rb +++ b/test/test-helper/models/model_with_additional_properties_of_model_array_type.rb @@ -7,10 +7,10 @@ class ModelWithAdditionalPropertiesOfModelArrayType < BaseWithAdditionalProperti private def self.get_additional_properties_from_hash(new_hash) - CoreLibrary::APIHelper.get_additional_properties( + CoreLibrary::ApiHelper.get_additional_properties( new_hash, - Proc.new { |item| Evening.from_dictionary(item) }, - as_array: true + Proc.new { |item| Evening.from_hash(item) }, + is_array: true ) end end diff --git a/test/test-helper/models/model_with_additional_properties_of_model_dict_type.rb b/test/test-helper/models/model_with_additional_properties_of_model_dict_type.rb index efbd6fb..6288888 100644 --- a/test/test-helper/models/model_with_additional_properties_of_model_dict_type.rb +++ b/test/test-helper/models/model_with_additional_properties_of_model_dict_type.rb @@ -7,10 +7,10 @@ class ModelWithAdditionalPropertiesOfModelDictType < BaseWithAdditionalPropertie private def self.get_additional_properties_from_hash(new_hash) - CoreLibrary::APIHelper.get_additional_properties( + CoreLibrary::ApiHelper.get_additional_properties( new_hash, - Proc.new { |item| Evening.from_dictionary(item) }, - as_dict: true + Proc.new { |item| Evening.from_hash(item) }, + is_dict: true ) end end diff --git a/test/test-helper/models/model_with_additional_properties_of_model_type.rb b/test/test-helper/models/model_with_additional_properties_of_model_type.rb index e01471a..818aaec 100644 --- a/test/test-helper/models/model_with_additional_properties_of_model_type.rb +++ b/test/test-helper/models/model_with_additional_properties_of_model_type.rb @@ -6,9 +6,9 @@ class ModelWithAdditionalPropertiesOfModelType < BaseWithAdditionalProperties private def self.get_additional_properties_from_hash(new_hash) - CoreLibrary::APIHelper.get_additional_properties( + CoreLibrary::ApiHelper.get_additional_properties( new_hash, - Proc.new { |item| Evening.from_dictionary(item) } + Proc.new { |item| Evening.from_hash(item) } ) end end diff --git a/test/test-helper/models/model_with_additional_properties_of_primitive_array_type.rb b/test/test-helper/models/model_with_additional_properties_of_primitive_array_type.rb index b90333f..0449e34 100644 --- a/test/test-helper/models/model_with_additional_properties_of_primitive_array_type.rb +++ b/test/test-helper/models/model_with_additional_properties_of_primitive_array_type.rb @@ -5,10 +5,10 @@ class ModelWithAdditionalPropertiesOfPrimitiveArrayType < BaseWithAdditionalProp private def self.get_additional_properties_from_hash(new_hash) - CoreLibrary::APIHelper.get_additional_properties( + CoreLibrary::ApiHelper.get_additional_properties( new_hash, Proc.new { |x| Integer(x) }, - as_array: true + is_array: true ) end end diff --git a/test/test-helper/models/model_with_additional_properties_of_primitive_dict_type.rb b/test/test-helper/models/model_with_additional_properties_of_primitive_dict_type.rb index 5c57ac1..05d6d94 100644 --- a/test/test-helper/models/model_with_additional_properties_of_primitive_dict_type.rb +++ b/test/test-helper/models/model_with_additional_properties_of_primitive_dict_type.rb @@ -5,11 +5,11 @@ class ModelWithAdditionalPropertiesOfPrimitiveDictType < BaseWithAdditionalPrope private def self.get_additional_properties_from_hash(new_hash) - CoreLibrary::APIHelper.get_additional_properties( + CoreLibrary::ApiHelper.get_additional_properties( new_hash, Proc.new { |x| Integer(x) }, - as_array: false, - as_dict: true + is_array: false, + is_dict: true ) end end diff --git a/test/test-helper/models/model_with_additional_properties_of_primitive_type.rb b/test/test-helper/models/model_with_additional_properties_of_primitive_type.rb index ff3082b..40b2b58 100644 --- a/test/test-helper/models/model_with_additional_properties_of_primitive_type.rb +++ b/test/test-helper/models/model_with_additional_properties_of_primitive_type.rb @@ -6,7 +6,7 @@ class ModelWithAdditionalPropertiesOfPrimitiveType < BaseWithAdditionalPropertie private def self.get_additional_properties_from_hash(new_hash) - CoreLibrary::APIHelper.get_additional_properties( + CoreLibrary::ApiHelper.get_additional_properties( new_hash, Proc.new { |x| Integer(x) } ) diff --git a/test/test-helper/models/model_with_additional_properties_of_type_combinator_primitive_type.rb b/test/test-helper/models/model_with_additional_properties_of_type_combinator_primitive_type.rb index 184db4f..20855a3 100644 --- a/test/test-helper/models/model_with_additional_properties_of_type_combinator_primitive_type.rb +++ b/test/test-helper/models/model_with_additional_properties_of_type_combinator_primitive_type.rb @@ -1,13 +1,14 @@ require_relative '../models/base_with_additional_properties' +require_relative '../models/union_type_lookup' module TestComponent class ModelWithAdditionalPropertiesOfTypeCombinatorPrimitiveType < BaseWithAdditionalProperties private def self.get_additional_properties_from_hash(new_hash) - CoreLibrary::APIHelper.get_additional_properties( + CoreLibrary::ApiHelper.get_additional_properties( new_hash, - Proc.new { |x| CoreLibrary::ApiHelper.deserialize_union_type(UnionTypeLookUp.get('scalarModelAnyOfRequired'), x) } + Proc.new { |x| CoreLibrary::ApiHelper.deserialize_union_type(UnionTypeLookUp.get('ScalarModelOneOfReqNullable'), x) } ) end end diff --git a/test/test-helper/models/union_type_lookup.rb b/test/test-helper/models/union_type_lookup.rb index 3a8654d..0d26c22 100644 --- a/test/test-helper/models/union_type_lookup.rb +++ b/test/test-helper/models/union_type_lookup.rb @@ -1,3 +1,4 @@ +require_relative '../models/evening' class UnionTypeLookUp # The `_union_types` stores type combinators as class variables (similar to a dictionary) # in Python, which is equivalent to a hash in Ruby. @@ -6,9 +7,9 @@ class UnionTypeLookUp # The format `UnionTypeLookUp._union_types` is similar to the Python class-level dictionary. @union_types = { 'ScalarModelAnyOfRequired' => CoreLibrary::AnyOf.new([CoreLibrary::LeafType.new(Float), CoreLibrary::LeafType.new(TrueClass)]), - 'ScalarModelOneOfReqNullable' => CoreLibrary::OneOf.new([CoreLibrary::LeafType.new(Integer), CoreLibrary::LeafType.new(String)], CoreLibrary::UnionTypeContext.create(is_nullable: true)), - 'ScalarModelOneOfOptional' => CoreLibrary::OneOf.new([CoreLibrary::LeafType.new(Integer), CoreLibrary::LeafType.new(Float), CoreLibrary::UnionTypeContext.new(String)], CoreLibrary::UnionTypeContext.create(is_optional: true)), - 'ScalarModelAnyOfOptNullable' => CoreLibrary::AnyOf.new([CoreLibrary::LeafType.new(Integer), CoreLibrary::LeafType.new(TrueClass)], CoreLibrary::UnionTypeContext.create(is_optional: true, is_nullable: true)), + 'ScalarModelOneOfReqNullable' => CoreLibrary::OneOf.new([CoreLibrary::LeafType.new(TestComponent::Evening), CoreLibrary::LeafType.new(String)]), + 'ScalarModelOneOfOptional' => CoreLibrary::OneOf.new([CoreLibrary::LeafType.new(Integer), CoreLibrary::LeafType.new(Float)]), + 'ScalarModelAnyOfOptNullable' => CoreLibrary::AnyOf.new([CoreLibrary::LeafType.new(Integer), CoreLibrary::LeafType.new(TrueClass)]), 'ScalarTypes' => CoreLibrary::OneOf.new([CoreLibrary::LeafType.new(Float), CoreLibrary::LeafType.new(TrueClass)]) }