Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ jobs:
- name: Setup Ruby and install gems
uses: ruby/setup-ruby@v1
with:
ruby-version: 2.7
ruby-version: 3.4.4
bundler-cache: true

- name: Run linters
Expand All @@ -26,7 +26,7 @@ jobs:
runs-on: ubuntu-latest
strategy:
matrix:
ruby-version: [2.6, 2.7, 3.0]
ruby-version: [3.2, 3.3, 3.4.4]
steps:
- name: Checkout code
uses: actions/checkout@v2
Expand Down
6 changes: 1 addition & 5 deletions .rubocop.yml
Original file line number Diff line number Diff line change
@@ -1,11 +1,7 @@
AllCops:
TargetRubyVersion: 2.6
TargetRubyVersion: 3.0
NewCops: enable

Metrics/BlockLength:
Exclude:
- 'spec/**/*'

Style/OpenStructUse:
Exclude:
- 'spec/**/*'
2 changes: 1 addition & 1 deletion .ruby-version
Original file line number Diff line number Diff line change
@@ -1 +1 @@
2.7.2
3.4.4
111 changes: 110 additions & 1 deletion lib/microcms.rb
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,99 @@ def client
end
end

# ResponseObject: replacement for OpenStruct
class ResponseObject
def initialize(hash = {})
@data = hash.transform_keys(&:to_sym)
@data.each do |key, value|
@data[key] = convert_value(value)
end
end

def ==(other)
case other
when ResponseObject
@data == other.instance_variable_get(:@data)
when Hash
@data == other.transform_keys(&:to_sym)
else
false
end
end

def to_h
@data.transform_values { |value|
case value
when ResponseObject
value.to_h
when Array
value.map { |item| item.is_a?(ResponseObject) ? item.to_h : item }
else
value
end
}
end

def [](key)
@data[key.to_sym]
end

def []=(key, value)
@data[key.to_sym] = convert_value(value)
end

def method_missing(method_name, *args, &block)
method_str = method_name.to_s

if method_str.end_with?('=')
key = method_str.chomp('=').to_sym
@data[key] = convert_value(args.first)
elsif @data.key?(method_name)
@data[method_name]
else
super
end
end

def respond_to_missing?(method_name, include_private = false)
method_str = method_name.to_s
method_str.end_with?('=') || @data.key?(method_name) || super
end

def delete_field(key)
@data.delete(key.to_sym)
end

def keys
@data.keys
end

def values
@data.values
end

def each(&block)
@data.each(&block)
end

def inspect
"#<#{self.class.name} #{@data.inspect}>"
end

private

def convert_value(value)
case value
when Hash
ResponseObject.new(value)
when Array
value.map { |item| convert_value(item) }
else
value
end
end
end

# HttpUtil
module HttpUtil
def send_http_request(method, endpoint, path, query = nil, body = nil)
Expand All @@ -30,7 +123,7 @@ def send_http_request(method, endpoint, path, query = nil, body = nil)

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

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

private
Expand Down Expand Up @@ -75,6 +168,22 @@ def build_http(uri)

http
end

def parse_json_response(body)
parsed = JSON.parse(body)
convert_to_object(parsed)
end

def convert_to_object(obj)
case obj
when Hash
ResponseObject.new(obj)
when Array
obj.map { |item| convert_to_object(item) }
else
obj
end
end
end

# Client
Expand Down
2 changes: 1 addition & 1 deletion microcms.gemspec
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ Gem::Specification.new do |spec|
spec.summary = 'microCMS Ruby SDK'
spec.description = 'microCMS Ruby SDK'
spec.homepage = 'https://github.com/microcmsio/microcms-ruby-sdk'
spec.required_ruby_version = Gem::Requirement.new('>= 2.6.0')
spec.required_ruby_version = Gem::Requirement.new('>= 3.4.4')

spec.metadata['homepage_uri'] = spec.homepage
spec.metadata['source_code_uri'] = spec.homepage
Expand Down
12 changes: 6 additions & 6 deletions spec/microcms_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,7 @@

res = client.list('endpoint')

expect(res.contents).to eq [OpenStruct.new(content)]
expect(res.contents).to eq [MicroCMS::ResponseObject.new(content)]
end
end

Expand All @@ -87,7 +87,7 @@

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

expect(res).to eq OpenStruct.new(content)
expect(res).to eq MicroCMS::ResponseObject.new(content)
end
end

Expand All @@ -104,7 +104,7 @@

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

expect(res).to eq OpenStruct.new({ id: 'bar' })
expect(res).to eq MicroCMS::ResponseObject.new({ id: 'bar' })
end
end

Expand All @@ -122,7 +122,7 @@

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

expect(res).to eq OpenStruct.new({ id: 'bar' })
expect(res).to eq MicroCMS::ResponseObject.new({ id: 'bar' })
end
end

Expand All @@ -140,7 +140,7 @@

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

expect(res).to eq OpenStruct.new({ id: 'bar' })
expect(res).to eq MicroCMS::ResponseObject.new({ id: 'bar' })
end
end

Expand All @@ -158,7 +158,7 @@

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

expect(res).to eq OpenStruct.new({ id: 'bar' })
expect(res).to eq MicroCMS::ResponseObject.new({ id: 'bar' })
end
end

Expand Down
41 changes: 41 additions & 0 deletions test_response_object.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
#!/usr/bin/env ruby

# Simple test to verify ResponseObject functionality
require_relative 'lib/microcms'

# Test ResponseObject creation and access
puts "Testing ResponseObject..."

# Test 1: Basic creation and access
response = MicroCMS::ResponseObject.new({ id: 'test123', name: 'Test Article' })
puts "✓ Basic creation: #{response.id} - #{response.name}"

# Test 2: Nested objects
nested_data = {
id: 'article1',
title: 'Hello World',
author: {
id: 'author1',
name: 'John Doe'
},
tags: ['ruby', 'programming']
}

nested_response = MicroCMS::ResponseObject.new(nested_data)
puts "✓ Nested access: #{nested_response.author.name}"
puts "✓ Array access: #{nested_response.tags}"

# Test 3: Equality comparison
response1 = MicroCMS::ResponseObject.new({ id: 'test' })
response2 = MicroCMS::ResponseObject.new({ id: 'test' })
puts "✓ Equality test: #{response1 == response2}"

# Test 4: Hash conversion
hash_result = nested_response.to_h
puts "✓ Hash conversion: #{hash_result[:author][:name]}"

# Test 5: delete_field functionality
response.delete_field(:name)
puts "✓ Delete field test: name should be nil: #{response.name.nil?}"

puts "\nAll ResponseObject tests passed! ✅"