Skip to content

Commit f91eaf0

Browse files
committed
refactor: replace the openStruct
1 parent ed747f6 commit f91eaf0

File tree

6 files changed

+159
-13
lines changed

6 files changed

+159
-13
lines changed

.github/workflows/ci.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ jobs:
2626
runs-on: ubuntu-latest
2727
strategy:
2828
matrix:
29-
ruby-version: [2.6, 2.7, 3.0, 3.4.4]
29+
ruby-version: [3.2, 3.3, 3.4.4]
3030
steps:
3131
- name: Checkout code
3232
uses: actions/checkout@v2

.rubocop.yml

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,3 @@ AllCops:
55
Metrics/BlockLength:
66
Exclude:
77
- 'spec/**/*'
8-
9-
Style/OpenStructUse:
10-
Exclude:
11-
- 'spec/**/*'

lib/microcms.rb

Lines changed: 110 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,99 @@ def client
2020
end
2121
end
2222

23+
# ResponseObject: replacement for OpenStruct
24+
class ResponseObject
25+
def initialize(hash = {})
26+
@data = hash.transform_keys(&:to_sym)
27+
@data.each do |key, value|
28+
@data[key] = convert_value(value)
29+
end
30+
end
31+
32+
def ==(other)
33+
case other
34+
when ResponseObject
35+
@data == other.instance_variable_get(:@data)
36+
when Hash
37+
@data == other.transform_keys(&:to_sym)
38+
else
39+
false
40+
end
41+
end
42+
43+
def to_h
44+
@data.transform_values { |value|
45+
case value
46+
when ResponseObject
47+
value.to_h
48+
when Array
49+
value.map { |item| item.is_a?(ResponseObject) ? item.to_h : item }
50+
else
51+
value
52+
end
53+
}
54+
end
55+
56+
def [](key)
57+
@data[key.to_sym]
58+
end
59+
60+
def []=(key, value)
61+
@data[key.to_sym] = convert_value(value)
62+
end
63+
64+
def method_missing(method_name, *args, &block)
65+
method_str = method_name.to_s
66+
67+
if method_str.end_with?('=')
68+
key = method_str.chomp('=').to_sym
69+
@data[key] = convert_value(args.first)
70+
elsif @data.key?(method_name)
71+
@data[method_name]
72+
else
73+
super
74+
end
75+
end
76+
77+
def respond_to_missing?(method_name, include_private = false)
78+
method_str = method_name.to_s
79+
method_str.end_with?('=') || @data.key?(method_name) || super
80+
end
81+
82+
def delete_field(key)
83+
@data.delete(key.to_sym)
84+
end
85+
86+
def keys
87+
@data.keys
88+
end
89+
90+
def values
91+
@data.values
92+
end
93+
94+
def each(&block)
95+
@data.each(&block)
96+
end
97+
98+
def inspect
99+
"#<#{self.class.name} #{@data.inspect}>"
100+
end
101+
102+
private
103+
104+
def convert_value(value)
105+
case value
106+
when Hash
107+
ResponseObject.new(value)
108+
when Array
109+
value.map { |item| convert_value(item) }
110+
else
111+
value
112+
end
113+
end
114+
end
115+
23116
# HttpUtil
24117
module HttpUtil
25118
def send_http_request(method, endpoint, path, query = nil, body = nil)
@@ -30,7 +123,7 @@ def send_http_request(method, endpoint, path, query = nil, body = nil)
30123

31124
raise APIError.new(status_code: res.code.to_i, body: res.body) if res.code.to_i >= 400
32125

33-
JSON.parse(res.body, object_class: OpenStruct) if res.header['Content-Type'].include?('application/json') # rubocop:disable Style/OpenStructUse
126+
parse_json_response(res.body) if res.header['Content-Type'].include?('application/json')
34127
end
35128

36129
private
@@ -75,6 +168,22 @@ def build_http(uri)
75168

76169
http
77170
end
171+
172+
def parse_json_response(body)
173+
parsed = JSON.parse(body)
174+
convert_to_object(parsed)
175+
end
176+
177+
def convert_to_object(obj)
178+
case obj
179+
when Hash
180+
ResponseObject.new(obj)
181+
when Array
182+
obj.map { |item| convert_to_object(item) }
183+
else
184+
obj
185+
end
186+
end
78187
end
79188

80189
# Client

microcms.gemspec

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ Gem::Specification.new do |spec|
1010
spec.summary = 'microCMS Ruby SDK'
1111
spec.description = 'microCMS Ruby SDK'
1212
spec.homepage = 'https://github.com/microcmsio/microcms-ruby-sdk'
13-
spec.required_ruby_version = Gem::Requirement.new('>= 3.0.0')
13+
spec.required_ruby_version = Gem::Requirement.new('>= 3.4.4')
1414

1515
spec.metadata['homepage_uri'] = spec.homepage
1616
spec.metadata['source_code_uri'] = spec.homepage

spec/microcms_spec.rb

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -72,7 +72,7 @@
7272

7373
res = client.list('endpoint')
7474

75-
expect(res.contents).to eq [OpenStruct.new(content)]
75+
expect(res.contents).to eq [MicroCMS::ResponseObject.new(content)]
7676
end
7777
end
7878

@@ -87,7 +87,7 @@
8787

8888
res = client.get('endpoint', 'foo')
8989

90-
expect(res).to eq OpenStruct.new(content)
90+
expect(res).to eq MicroCMS::ResponseObject.new(content)
9191
end
9292
end
9393

@@ -104,7 +104,7 @@
104104

105105
res = client.create('endpoint', { text: 'Hello, new content!' })
106106

107-
expect(res).to eq OpenStruct.new({ id: 'bar' })
107+
expect(res).to eq MicroCMS::ResponseObject.new({ id: 'bar' })
108108
end
109109
end
110110

@@ -122,7 +122,7 @@
122122

123123
res = client.create('endpoint', { id: 'bar', text: 'Hello, new content!' })
124124

125-
expect(res).to eq OpenStruct.new({ id: 'bar' })
125+
expect(res).to eq MicroCMS::ResponseObject.new({ id: 'bar' })
126126
end
127127
end
128128

@@ -140,7 +140,7 @@
140140

141141
res = client.create('endpoint', { text: 'Hello, new content!' }, { status: 'draft' })
142142

143-
expect(res).to eq OpenStruct.new({ id: 'bar' })
143+
expect(res).to eq MicroCMS::ResponseObject.new({ id: 'bar' })
144144
end
145145
end
146146

@@ -158,7 +158,7 @@
158158

159159
res = client.update('endpoint', { id: 'bar', text: 'Hello, new content!' })
160160

161-
expect(res).to eq OpenStruct.new({ id: 'bar' })
161+
expect(res).to eq MicroCMS::ResponseObject.new({ id: 'bar' })
162162
end
163163
end
164164

test_response_object.rb

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
#!/usr/bin/env ruby
2+
3+
# Simple test to verify ResponseObject functionality
4+
require_relative 'lib/microcms'
5+
6+
# Test ResponseObject creation and access
7+
puts "Testing ResponseObject..."
8+
9+
# Test 1: Basic creation and access
10+
response = MicroCMS::ResponseObject.new({ id: 'test123', name: 'Test Article' })
11+
puts "✓ Basic creation: #{response.id} - #{response.name}"
12+
13+
# Test 2: Nested objects
14+
nested_data = {
15+
id: 'article1',
16+
title: 'Hello World',
17+
author: {
18+
id: 'author1',
19+
name: 'John Doe'
20+
},
21+
tags: ['ruby', 'programming']
22+
}
23+
24+
nested_response = MicroCMS::ResponseObject.new(nested_data)
25+
puts "✓ Nested access: #{nested_response.author.name}"
26+
puts "✓ Array access: #{nested_response.tags}"
27+
28+
# Test 3: Equality comparison
29+
response1 = MicroCMS::ResponseObject.new({ id: 'test' })
30+
response2 = MicroCMS::ResponseObject.new({ id: 'test' })
31+
puts "✓ Equality test: #{response1 == response2}"
32+
33+
# Test 4: Hash conversion
34+
hash_result = nested_response.to_h
35+
puts "✓ Hash conversion: #{hash_result[:author][:name]}"
36+
37+
# Test 5: delete_field functionality
38+
response.delete_field(:name)
39+
puts "✓ Delete field test: name should be nil: #{response.name.nil?}"
40+
41+
puts "\nAll ResponseObject tests passed! ✅"

0 commit comments

Comments
 (0)