Skip to content

Commit

Permalink
Merge pull request #265 from okuramasafumi/renew-inflector-api
Browse files Browse the repository at this point in the history
  • Loading branch information
okuramasafumi authored Nov 7, 2022
2 parents 97ed7a9 + 4e06316 commit 5221582
Show file tree
Hide file tree
Showing 12 changed files with 112 additions and 59 deletions.
31 changes: 27 additions & 4 deletions lib/alba.rb
Original file line number Diff line number Diff line change
Expand Up @@ -7,10 +7,10 @@
# Core module
module Alba
class << self
attr_reader :backend, :encoder, :inferring
attr_reader :backend, :encoder

# Accessor for inflector, a module responsible for inflecting strings
attr_accessor :inflector
# Getter for inflector, a module responsible for inflecting strings
attr_reader :inflector

# Set the backend, which actually serializes object into JSON
#
Expand Down Expand Up @@ -54,14 +54,36 @@ def serialize(object, root_key: nil, &block)
# @param with [Symbol, Class, Module] inflector
# When it's a Symbol, it sets inflector with given name
# When it's a Class or a Module, it sets given object to inflector
# @deprecated Use {#inflector=} instead
def enable_inference!(with:)
Alba::Deprecation.warn('Alba.enable_inference! is deprecated. Use `Alba.inflector=` instead.')
@inflector = inflector_from(with)
@inferring = true
end

# Disable inference for key and resource name
#
# @deprecated Use {#inflector=} instead
def disable_inference!
Alba::Deprecation.warn('Alba.disable_inference! is deprecated. Use `Alba.inflector = nil` instead.')
@inferring = false
@inflector = nil
end

# @deprecated Use {#inflector} instead
# @return [Boolean] whether inference is enabled or not
def inferring
Alba::Deprecation.warn('Alba.inferring is deprecated. Use `Alba.inflector` instead.')
@inferring
end

# Set an inflector
#
# @param inflector [Symbol, Class, Module] inflector
# When it's a Symbol, it accepts `:default`, `:active_support` or `:dry`
# When it's a Class or a Module, it should have some methods, see {Alba::DefaultInflector}
def inflector=(inflector)
@inflector = inflector_from(inflector)
end

# @param block [Block] resource body
Expand All @@ -77,7 +99,7 @@ def resource_class(&block)
# @param nesting [String, nil] namespace Alba tries to find resource class in
# @return [Class<Alba::Resource>] resource class
def infer_resource_class(name, nesting: nil)
raise Alba::Error, 'Inference is disabled so Alba cannot infer resource name. Use `Alba.enable_inference!` before use.' unless Alba.inferring
raise Alba::Error, 'Inference is disabled so Alba cannot infer resource name. Set inflector before use.' unless Alba.inflector

const_parent = nesting.nil? ? Object : Object.const_get(nesting)
const_parent.const_get("#{inflector.classify(name)}Resource")
Expand All @@ -95,6 +117,7 @@ def reset!

def inflector_from(name_or_module)
case name_or_module
when nil then nil
when :default, :active_support
require_relative 'alba/default_inflector'
Alba::DefaultInflector
Expand Down
4 changes: 2 additions & 2 deletions lib/alba/association.rb
Original file line number Diff line number Diff line change
Expand Up @@ -63,10 +63,10 @@ def assign_resource(nesting, key_transformation, block)
klass.transform_keys(key_transformation)
klass.class_eval(&block)
klass
elsif Alba.inferring
elsif Alba.inflector
Alba.infer_resource_class(@name, nesting: nesting)
else
raise ArgumentError, 'When Alba.inferring is false, either resource or block is required'
raise ArgumentError, 'When Alba.inflector is nil, either resource or block is required'
end
end

Expand Down
8 changes: 4 additions & 4 deletions lib/alba/resource.rb
Original file line number Diff line number Diff line change
Expand Up @@ -149,7 +149,7 @@ def fetch_key
end

def _key_for_collection
if Alba.inferring
if Alba.inflector
@_key_for_collection == true ? resource_name(pluralized: true) : @_key_for_collection.to_s
else
@_key_for_collection == true ? raise_root_key_inference_error : @_key_for_collection.to_s
Expand All @@ -158,7 +158,7 @@ def _key_for_collection

# @return [String]
def _key
if Alba.inferring
if Alba.inflector
@_key == true ? resource_name(pluralized: false) : @_key.to_s
else
@_key == true ? raise_root_key_inference_error : @_key.to_s
Expand All @@ -174,7 +174,7 @@ def resource_name(pluralized: false)
end

def raise_root_key_inference_error
raise Alba::Error, 'You must call Alba.enable_inference! to set root_key to true for inferring root key.'
raise Alba::Error, 'You must set inflector when setting root key as true.'
end

def transforming_root_key?
Expand Down Expand Up @@ -237,7 +237,7 @@ def transform_key(key) # rubocop:disable Metrics/CyclomaticComplexity
return key if @_transform_type == :none || key.empty? # We can skip transformation

inflector = Alba.inflector
raise Alba::Error, 'Inflector is nil. You can set inflector with `Alba.enable_inference!(with: :active_support)` for example.' unless inflector
raise Alba::Error, 'Inflector is nil. You must set inflector before transforming keys.' unless inflector

case @_transform_type # rubocop:disable Style/MissingElse
when :camel then inflector.camelize(key)
Expand Down
30 changes: 25 additions & 5 deletions test/alba_test.rb
Original file line number Diff line number Diff line change
Expand Up @@ -214,7 +214,7 @@ class UserResource
end

def test_it_serializes_object_with_inferred_resource_when_inference_is_enabled
Alba.enable_inference!(with: :active_support)
Alba.inflector = :active_support
assert_equal(
'{"id":1,"articles":[{"title":"Hello World!","body":"Hello World!!!"}]}',
Alba.serialize(@user)
Expand All @@ -223,20 +223,40 @@ def test_it_serializes_object_with_inferred_resource_when_inference_is_enabled
'{"user":{"id":1,"articles":[{"title":"Hello World!","body":"Hello World!!!"}]}}',
Alba.serialize(@user, root_key: :user)
)
Alba.disable_inference!
Alba.inflector = nil
end

def test_it_raises_error_when_trying_to_infer_resource_when_inference_is_disabled
Alba.disable_inference!
Alba.inflector = nil
assert_raises(Alba::Error) { Alba.serialize(@user) }
end

class Foo # rubocop:disable Lint/EmptyClass
end

def test_it_raises_error_when_inferred_resource_does_not_exist_even_when_infernce_is_enabled
Alba.enable_inference!(with: :active_support)
Alba.inflector = :active_support
assert_raises(NameError) { Alba.serialize(Foo.new) }
Alba.disable_inference!
Alba.inflector = nil
end

# Deprecated methods

def test_enable_inference_is_deprecated
assert_output(nil, /Alba.enable_inference! is deprecated. Use `Alba.inflector=` instead.\n/) do
Alba.enable_inference!(with: :active_support)
end
end

def test_disable_inference_is_deprecated
assert_output(nil, /Alba.disable_inference! is deprecated. Use `Alba.inflector = nil` instead.\n/) do
Alba.disable_inference!
end
end

def test_inferring_is_deprecated
assert_output(nil, /Alba.inferring is deprecated. Use `Alba.inflector` instead.\n/) do
Alba.inferring
end
end
end
6 changes: 3 additions & 3 deletions test/dependencies/test_dependencies.rb
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ def setup
end

def teardown
Alba.disable_inference!
Alba.inflector = nil
Alba.backend = nil
end

Expand All @@ -31,7 +31,7 @@ def test_alba_error_is_raised_if_keys_should_be_transformed_but_active_support_i
err = assert_raises(Alba::Error) do
UserResourceCamel.new(@user).serialize
end
assert_equal('Inflector is nil. You can set inflector with `Alba.enable_inference!(with: :active_support)` for example.', err.message)
assert_equal('Inflector is nil. You must set inflector before transforming keys.', err.message)
end

def test_it_warns_when_set_backend_as_active_support_but_active_support_is_not_available
Expand All @@ -50,7 +50,7 @@ def test_alba_error_is_raise_if_root_key_is_set_to_true
err = assert_raises(Alba::Error) do
UserResourceWithRootKey.new(@user).serialize
end
assert_equal('You must call Alba.enable_inference! to set root_key to true for inferring root key.', err.message)
assert_equal('You must set inflector when setting root key as true.', err.message)
end
elsif ENV['BUNDLE_GEMFILE'] == File.expand_path('gemfiles/without_oj.gemfile')
def test_it_warns_when_set_backend_as_oj_but_oj_is_not_available
Expand Down
32 changes: 32 additions & 0 deletions test/support/custom_inflector.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
# Fake implementation of custom inflector
module CustomInflector
module_function

def camelize(str)
"camelized_#{str}"
end

def camelize_lower(str)
str
end

def dasherize(str)
str
end

def classify(str)
str
end

def demodulize(str)
str.split('::').last
end

def underscore(str)
str.gsub(/::/, '/').gsub(/([A-Z]+)([A-Z][a-z])/, '\1_\2').gsub(/([a-z\d])([A-Z])/, '\1_\2').tr('-', '_').downcase
end

def pluralize(str)
"#{str}s"
end
end
4 changes: 2 additions & 2 deletions test/usecases/circular_association_test.rb
Original file line number Diff line number Diff line change
Expand Up @@ -85,7 +85,7 @@ class BookResource
end

def setup
Alba.enable_inference!(with: :active_support)
Alba.inflector = :active_support

@authors = Array.new(100) do
Author.new(
Expand Down Expand Up @@ -122,7 +122,7 @@ def setup
end

def teardown
Alba.disable_inference!
Alba.inflector = nil
end

def test_within_option_works_for_serialize
Expand Down
11 changes: 3 additions & 8 deletions test/usecases/key_transform_test.rb
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
require_relative '../test_helper'
require_relative '../support/custom_inflector'

class KeyTransformTest < Minitest::Test
class User
Expand Down Expand Up @@ -64,14 +65,8 @@ class BankAccountRootFalseResource < BankAccountResource
transform_keys :dash, root: false
end

class CustomInflector
def camelize(key)
"camelized_#{key}"
end
end

def setup
Alba.enable_inference!(with: :active_support)
Alba.inflector = :active_support

@bank_account = BankAccount.new(123_456_789)
@user = User.new(1, 'Masafumi', 'Okura', @bank_account)
Expand Down Expand Up @@ -143,7 +138,7 @@ def test_transform_key_to_lower_camel_works_on_root_key_when_root_option_set_to_
end

def test_custom_inflector_is_used_if_defined
Alba.inflector = CustomInflector.new
Alba.inflector = CustomInflector
assert_equal(
'{"camelized_id":1,"camelized_first_name":"Masafumi","camelized_last_name":"Okura"}',
UserResourceCamel.new(@user).serialize
Expand Down
2 changes: 1 addition & 1 deletion test/usecases/many_test.rb
Original file line number Diff line number Diff line change
Expand Up @@ -134,7 +134,7 @@ def test_it_returns_correct_json_with_resource_option_string
end

def test_it_raises_error_when_no_resource_or_block_given_without_inference
Alba.disable_inference!
Alba.inflector = nil
resource = <<~RUBY
class UserResource6
include Alba::Resource
Expand Down
4 changes: 2 additions & 2 deletions test/usecases/nested_attribute_test.rb
Original file line number Diff line number Diff line change
Expand Up @@ -27,13 +27,13 @@ class UserResource

def setup
Alba.backend = nil
Alba.enable_inference!(with: :active_support)
Alba.inflector = :active_support

@user = User.new(1, 'Masafumi OKURA', '[email protected]', 'Tokyo', '0000000')
end

def teardown
Alba.disable_inference!
Alba.inflector = nil
end

def test_nested_attribute_becomes_nested_hash
Expand Down
8 changes: 4 additions & 4 deletions test/usecases/one_test.rb
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

class OneTest < MiniTest::Test
def teardown
Alba.enable_inference!(with: :active_support)
Alba.inflector = :active_support
end

class User
Expand Down Expand Up @@ -159,17 +159,17 @@ def create_resource_class

one :profile
end
OneTest.const_set('UserResource', klass)
OneTest.const_set(:UserResource, klass)
klass
end
end

def test_it_raises_error_when_no_resource_or_block_given_without_inference
Alba.disable_inference!
Alba.inflector = nil
assert_raises(ArgumentError) { create_resource_class.call }
end

Alba.enable_inference!(with: :active_support)
Alba.inflector = :active_support
class UserResource7
include Alba::Resource

Expand Down
Loading

0 comments on commit 5221582

Please sign in to comment.