diff --git a/lib/openai/internal/type/base_model.rb b/lib/openai/internal/type/base_model.rb index d1e25f0c7..10688bbf3 100644 --- a/lib/openai/internal/type/base_model.rb +++ b/lib/openai/internal/type/base_model.rb @@ -83,12 +83,15 @@ def fields target = type_fn.call state = OpenAI::Internal::Type::Converter.new_coerce_state(translate_names: false) coerced = OpenAI::Internal::Type::Converter.coerce(target, value, state: state) - error = @coerced.store(name_sym, state.fetch(:error) || true) + status = state.fetch(:error) || true + @coerced.store(name_sym, status) stored = - case [target, error] - in [OpenAI::Internal::Type::Converter | Symbol, nil] + case [target, status, value] + in [OpenAI::Internal::Type::Converter | Symbol, true, ^target] + value + in [OpenAI::Internal::Type::Converter | Symbol, true, _] coerced - else + else # rubocop:disable Lint/DuplicateBranch value end @data.store(name_sym, stored) diff --git a/test/openai/internal/type/base_model_test.rb b/test/openai/internal/type/base_model_test.rb index 475329444..20508f417 100644 --- a/test/openai/internal/type/base_model_test.rb +++ b/test/openai/internal/type/base_model_test.rb @@ -345,6 +345,15 @@ class M6 < M1 optional :b, M6 end + class M7 < OpenAI::Internal::Type::BaseModel + required :a, Integer + end + + class M8 < OpenAI::Internal::Type::BaseModel + optional :item, M7 + optional :items, OpenAI::Internal::Type::ArrayOf[M7] + end + def test_coerce cases = { [M1, {}] => [{yes: 1, no: 1}, {}], @@ -448,6 +457,23 @@ def test_accessors end end + def test_constructor_stores_coerced_nested_models + model = M8.new(item: {a: 1}, items: [{a: 2}]) + + assert_instance_of(M7, model.item) + assert_instance_of(M7, model.items.fetch(0)) + assert_instance_of(M7, model.to_h.fetch(:item)) + assert_instance_of(M7, model.to_h.fetch(:items).fetch(0)) + + model.item = {a: 3} + model.items = [{a: 4}] + + assert_instance_of(M7, model.item) + assert_instance_of(M7, model.items.fetch(0)) + assert_instance_of(M7, model.to_h.fetch(:item)) + assert_instance_of(M7, model.to_h.fetch(:items).fetch(0)) + end + def test_inplace_modification m1 = M6.new(a: []) m1.a << M6.new(a: [])