From 3d640b89d50311df6e2589118d0ca995cde92996 Mon Sep 17 00:00:00 2001 From: Hermann Mayer Date: Thu, 4 Dec 2025 06:38:04 +0100 Subject: [PATCH 1/2] Added a safety guard for double wrapping. Signed-off-by: Hermann Mayer --- lib/recursive_open_struct.rb | 1 + spec/recursive_open_struct/wrapping_spec.rb | 71 +++++++++++++++++++++ 2 files changed, 72 insertions(+) create mode 100644 spec/recursive_open_struct/wrapping_spec.rb diff --git a/lib/recursive_open_struct.rb b/lib/recursive_open_struct.rb index 9e435fe..a0d01ea 100644 --- a/lib/recursive_open_struct.rb +++ b/lib/recursive_open_struct.rb @@ -29,6 +29,7 @@ def self.default_options end def initialize(hash=nil, passed_options={}) + hash = hash.to_h if [hash.is_a?(RecursiveOpenStruct), hash.is_a?(OpenStruct)].any? hash ||= {} @options = self.class.default_options.merge!(passed_options).freeze diff --git a/spec/recursive_open_struct/wrapping_spec.rb b/spec/recursive_open_struct/wrapping_spec.rb new file mode 100644 index 0000000..dd7a5f9 --- /dev/null +++ b/spec/recursive_open_struct/wrapping_spec.rb @@ -0,0 +1,71 @@ +require_relative '../spec_helper' +require 'recursive_open_struct' + +describe RecursiveOpenStruct do + describe 'wrapping RecursiveOpenStruct' do + let(:h) { { :blah => { :another => 'value' } } } + subject(:ros) { RecursiveOpenStruct.new(RecursiveOpenStruct.new(h)) } + + it 'can convert the entire hash tree back into a hash' do + expect(ros.to_h).to eq h + end + + it 'can access the flat keys' do + expect(ros.blah).to be_a(RecursiveOpenStruct) + end + + it 'can access the nested keys' do + expect(ros.blah.another).to eql('value') + end + + it 'can be inspected' do + expect(ros.inspect).to \ + eql('#') + end + end + + describe 'wrapping OpenStruct' do + let(:h) { { :blah => { :another => 'value' } } } + subject(:ros) { RecursiveOpenStruct.new(OpenStruct.new(h)) } + + it 'can convert the entire hash tree back into a hash' do + expect(ros.to_h).to eq h + end + + it 'can access the flat keys' do + expect(ros.blah).to be_a(RecursiveOpenStruct) + end + + it 'can access the nested keys' do + expect(ros.blah.another).to eql('value') + end + + it 'can be inspected' do + expect(ros.inspect).to \ + eql('#') + end + end + + describe 'wrapping a subclass' do + let(:h) { { :blah => { :another => 'value' } } } + let(:subclass) { Class.new(RecursiveOpenStruct) } + subject(:ros) { subclass.new(subclass.new(h)) } + + it 'can convert the entire hash tree back into a hash' do + expect(ros.to_h).to eq h + end + + it 'can access the flat keys' do + expect(ros.blah).to be_a(RecursiveOpenStruct) + end + + it 'can access the nested keys' do + expect(ros.blah.another).to eql('value') + end + + it 'can be inspected' do + expect(ros.inspect).to \ + end_with(' blah={another: "value"}>') + end + end +end From e3fd0155b42338f7514865340ecd92c31c45b003 Mon Sep 17 00:00:00 2001 From: Hermann Mayer Date: Fri, 5 Dec 2025 07:48:33 +0100 Subject: [PATCH 2/2] Corrected the specs for older Rubies (<3.4). Signed-off-by: Hermann Mayer --- spec/recursive_open_struct/wrapping_spec.rb | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/spec/recursive_open_struct/wrapping_spec.rb b/spec/recursive_open_struct/wrapping_spec.rb index dd7a5f9..7a6f2e4 100644 --- a/spec/recursive_open_struct/wrapping_spec.rb +++ b/spec/recursive_open_struct/wrapping_spec.rb @@ -20,7 +20,7 @@ it 'can be inspected' do expect(ros.inspect).to \ - eql('#') + match(/#)"value"}>/) end end @@ -42,7 +42,7 @@ it 'can be inspected' do expect(ros.inspect).to \ - eql('#') + match(/#)"value"}>/) end end @@ -64,8 +64,7 @@ end it 'can be inspected' do - expect(ros.inspect).to \ - end_with(' blah={another: "value"}>') + expect(ros.inspect).to match(/ blah={:?another(: |=>)"value"}>$/) end end end