From 4a184de70169cc7998f61b4001fc74335e37824d Mon Sep 17 00:00:00 2001 From: "L. Preston Sego III" Date: Wed, 7 Dec 2016 10:49:38 -0500 Subject: [PATCH] Swap out KeyTransform for CaseTransform (#1993) * delete KeyTransform, use CaseTransform * added changelog Conflicts: CHANGELOG.md --- CHANGELOG.md | 2 + active_model_serializers.gemspec | 1 + lib/active_model_serializers/adapter/base.rb | 4 +- .../adapter/json_api/deserialization.rb | 2 +- lib/active_model_serializers/key_transform.rb | 74 ----- .../key_transform_test.rb | 297 ------------------ test/benchmark/bm_transform.rb | 10 +- 7 files changed, 11 insertions(+), 379 deletions(-) delete mode 100644 lib/active_model_serializers/key_transform.rb delete mode 100644 test/active_model_serializers/key_transform_test.rb diff --git a/CHANGELOG.md b/CHANGELOG.md index fe24b77ec..21b3ac1da 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -10,6 +10,8 @@ Fixes: Misc: +- [#1993](https://github.com/rails-api/active_model_serializers/pull/1993) Swap out KeyTransform for CaseTransform gem for the possibility of native extension use (@NullVoxPopuli) + ### [v0.10.3 (2016-11-21)](https://github.com/rails-api/active_model_serializers/compare/v0.10.2...v0.10.3) Fixes: diff --git a/active_model_serializers.gemspec b/active_model_serializers.gemspec index 89327bc63..3581ce408 100644 --- a/active_model_serializers.gemspec +++ b/active_model_serializers.gemspec @@ -43,6 +43,7 @@ Gem::Specification.new do |spec| # 'thread_safe' spec.add_runtime_dependency 'jsonapi', '0.1.1.beta2' + spec.add_runtime_dependency 'case_transform', '>= 0.2' spec.add_development_dependency 'activerecord', rails_versions # arel diff --git a/lib/active_model_serializers/adapter/base.rb b/lib/active_model_serializers/adapter/base.rb index 7b60db70b..851583285 100644 --- a/lib/active_model_serializers/adapter/base.rb +++ b/lib/active_model_serializers/adapter/base.rb @@ -1,4 +1,4 @@ -require 'active_model_serializers/key_transform' +require 'case_transform' module ActiveModelSerializers module Adapter @@ -31,7 +31,7 @@ def self.transform(options) # @param options [Object] serializable resource options # @return [Symbol] the default transform for the adapter def self.transform_key_casing!(value, options) - KeyTransform.send(transform(options), value) + CaseTransform.send(transform(options), value) end def self.cache_key diff --git a/lib/active_model_serializers/adapter/json_api/deserialization.rb b/lib/active_model_serializers/adapter/json_api/deserialization.rb index 2e0e531dd..b79125ac4 100644 --- a/lib/active_model_serializers/adapter/json_api/deserialization.rb +++ b/lib/active_model_serializers/adapter/json_api/deserialization.rb @@ -205,7 +205,7 @@ def parse_relationships(relationships, options) # @api private def transform_keys(hash, options) transform = options[:key_transform] || :underscore - KeyTransform.send(transform, hash) + CaseTransform.send(transform, hash) end end end diff --git a/lib/active_model_serializers/key_transform.rb b/lib/active_model_serializers/key_transform.rb deleted file mode 100644 index d0e648e59..000000000 --- a/lib/active_model_serializers/key_transform.rb +++ /dev/null @@ -1,74 +0,0 @@ -require 'active_support/core_ext/hash/keys' - -module ActiveModelSerializers - module KeyTransform - module_function - - # Transforms values to UpperCamelCase or PascalCase. - # - # @example: - # "some_key" => "SomeKey", - # @see {https://github.com/rails/rails/blob/master/activesupport/lib/active_support/inflector/methods.rb#L66-L76 ActiveSupport::Inflector.camelize} - def camel(value) - case value - when Array then value.map { |item| camel(item) } - when Hash then value.deep_transform_keys! { |key| camel(key) } - when Symbol then camel(value.to_s).to_sym - when String then value.underscore.camelize - else value - end - end - - # Transforms values to camelCase. - # - # @example: - # "some_key" => "someKey", - # @see {https://github.com/rails/rails/blob/master/activesupport/lib/active_support/inflector/methods.rb#L66-L76 ActiveSupport::Inflector.camelize} - def camel_lower(value) - case value - when Array then value.map { |item| camel_lower(item) } - when Hash then value.deep_transform_keys! { |key| camel_lower(key) } - when Symbol then camel_lower(value.to_s).to_sym - when String then value.underscore.camelize(:lower) - else value - end - end - - # Transforms values to dashed-case. - # This is the default case for the JsonApi adapter. - # - # @example: - # "some_key" => "some-key", - # @see {https://github.com/rails/rails/blob/master/activesupport/lib/active_support/inflector/methods.rb#L185-L187 ActiveSupport::Inflector.dasherize} - def dash(value) - case value - when Array then value.map { |item| dash(item) } - when Hash then value.deep_transform_keys! { |key| dash(key) } - when Symbol then dash(value.to_s).to_sym - when String then value.underscore.dasherize - else value - end - end - - # Transforms values to underscore_case. - # This is the default case for deserialization in the JsonApi adapter. - # - # @example: - # "some-key" => "some_key", - # @see {https://github.com/rails/rails/blob/master/activesupport/lib/active_support/inflector/methods.rb#L89-L98 ActiveSupport::Inflector.underscore} - def underscore(value) - case value - when Array then value.map { |item| underscore(item) } - when Hash then value.deep_transform_keys! { |key| underscore(key) } - when Symbol then underscore(value.to_s).to_sym - when String then value.underscore - else value - end - end - - # Returns the value unaltered - def unaltered(value) - value - end - end -end diff --git a/test/active_model_serializers/key_transform_test.rb b/test/active_model_serializers/key_transform_test.rb deleted file mode 100644 index b4ff4d311..000000000 --- a/test/active_model_serializers/key_transform_test.rb +++ /dev/null @@ -1,297 +0,0 @@ -require 'test_helper' - -module ActiveModelSerializers - class KeyTransformTest < ActiveSupport::TestCase - def test_camel - obj = Object.new - scenarios = [ - { - value: { :"some-key" => 'value' }, - expected: { SomeKey: 'value' } - }, - { - value: { someKey: 'value' }, - expected: { SomeKey: 'value' } - }, - { - value: { some_key: 'value' }, - expected: { SomeKey: 'value' } - }, - { - value: { 'some-key' => 'value' }, - expected: { 'SomeKey' => 'value' } - }, - { - value: { 'someKey' => 'value' }, - expected: { 'SomeKey' => 'value' } - }, - { - value: { 'some_key' => 'value' }, - expected: { 'SomeKey' => 'value' } - }, - { - value: :"some-value", - expected: :SomeValue - }, - { - value: :some_value, - expected: :SomeValue - }, - { - value: :someValue, - expected: :SomeValue - }, - { - value: 'some-value', - expected: 'SomeValue' - }, - { - value: 'someValue', - expected: 'SomeValue' - }, - { - value: 'some_value', - expected: 'SomeValue' - }, - { - value: obj, - expected: obj - }, - { - value: nil, - expected: nil - }, - { - value: [ - { some_value: 'value' } - ], - expected: [ - { SomeValue: 'value' } - ] - } - ] - scenarios.each do |s| - result = ActiveModelSerializers::KeyTransform.camel(s[:value]) - assert_equal s[:expected], result - end - end - - def test_camel_lower - obj = Object.new - scenarios = [ - { - value: { :"some-key" => 'value' }, - expected: { someKey: 'value' } - }, - { - value: { SomeKey: 'value' }, - expected: { someKey: 'value' } - }, - { - value: { some_key: 'value' }, - expected: { someKey: 'value' } - }, - { - value: { 'some-key' => 'value' }, - expected: { 'someKey' => 'value' } - }, - { - value: { 'SomeKey' => 'value' }, - expected: { 'someKey' => 'value' } - }, - { - value: { 'some_key' => 'value' }, - expected: { 'someKey' => 'value' } - }, - { - value: :"some-value", - expected: :someValue - }, - { - value: :SomeValue, - expected: :someValue - }, - { - value: :some_value, - expected: :someValue - }, - { - value: 'some-value', - expected: 'someValue' - }, - { - value: 'SomeValue', - expected: 'someValue' - }, - { - value: 'some_value', - expected: 'someValue' - }, - { - value: obj, - expected: obj - }, - { - value: nil, - expected: nil - }, - { - value: [ - { some_value: 'value' } - ], - expected: [ - { someValue: 'value' } - ] - } - ] - scenarios.each do |s| - result = ActiveModelSerializers::KeyTransform.camel_lower(s[:value]) - assert_equal s[:expected], result - end - end - - def test_dash - obj = Object.new - scenarios = [ - { - value: { some_key: 'value' }, - expected: { :"some-key" => 'value' } - }, - { - value: { 'some_key' => 'value' }, - expected: { 'some-key' => 'value' } - }, - { - value: { SomeKey: 'value' }, - expected: { :"some-key" => 'value' } - }, - { - value: { 'SomeKey' => 'value' }, - expected: { 'some-key' => 'value' } - }, - { - value: { someKey: 'value' }, - expected: { :"some-key" => 'value' } - }, - { - value: { 'someKey' => 'value' }, - expected: { 'some-key' => 'value' } - }, - { - value: :some_value, - expected: :"some-value" - }, - { - value: :SomeValue, - expected: :"some-value" - }, - { - value: 'SomeValue', - expected: 'some-value' - }, - { - value: :someValue, - expected: :"some-value" - }, - { - value: 'someValue', - expected: 'some-value' - }, - { - value: obj, - expected: obj - }, - { - value: nil, - expected: nil - }, - { - value: [ - { 'some_value' => 'value' } - ], - expected: [ - { 'some-value' => 'value' } - ] - } - ] - scenarios.each do |s| - result = ActiveModelSerializers::KeyTransform.dash(s[:value]) - assert_equal s[:expected], result - end - end - - def test_underscore - obj = Object.new - scenarios = [ - { - value: { :"some-key" => 'value' }, - expected: { some_key: 'value' } - }, - { - value: { 'some-key' => 'value' }, - expected: { 'some_key' => 'value' } - }, - { - value: { SomeKey: 'value' }, - expected: { some_key: 'value' } - }, - { - value: { 'SomeKey' => 'value' }, - expected: { 'some_key' => 'value' } - }, - { - value: { someKey: 'value' }, - expected: { some_key: 'value' } - }, - { - value: { 'someKey' => 'value' }, - expected: { 'some_key' => 'value' } - }, - { - value: :"some-value", - expected: :some_value - }, - { - value: :SomeValue, - expected: :some_value - }, - { - value: :someValue, - expected: :some_value - }, - { - value: 'some-value', - expected: 'some_value' - }, - { - value: 'SomeValue', - expected: 'some_value' - }, - { - value: 'someValue', - expected: 'some_value' - }, - { - value: obj, - expected: obj - }, - { - value: nil, - expected: nil - }, - { - value: [ - { 'some-value' => 'value' } - ], - expected: [ - { 'some_value' => 'value' } - ] - } - ] - scenarios.each do |s| - result = ActiveModelSerializers::KeyTransform.underscore(s[:value]) - assert_equal s[:expected], result - end - end - end -end diff --git a/test/benchmark/bm_transform.rb b/test/benchmark/bm_transform.rb index 8af5298e9..97c655c01 100644 --- a/test/benchmark/bm_transform.rb +++ b/test/benchmark/bm_transform.rb @@ -25,21 +25,21 @@ serialization = adapter.as_json Benchmark.ams('camel', time: time, disable_gc: disable_gc) do - ActiveModelSerializers::KeyTransform.camel(serialization) + CaseTransform.camel(serialization) end Benchmark.ams('camel_lower', time: time, disable_gc: disable_gc) do - ActiveModelSerializers::KeyTransform.camel_lower(serialization) + CaseTransform.camel_lower(serialization) end Benchmark.ams('dash', time: time, disable_gc: disable_gc) do - ActiveModelSerializers::KeyTransform.dash(serialization) + CaseTransform.dash(serialization) end Benchmark.ams('unaltered', time: time, disable_gc: disable_gc) do - ActiveModelSerializers::KeyTransform.unaltered(serialization) + CaseTransform.unaltered(serialization) end Benchmark.ams('underscore', time: time, disable_gc: disable_gc) do - ActiveModelSerializers::KeyTransform.underscore(serialization) + CaseTransform.underscore(serialization) end