attributes-mapper 0.1.0 → 0.1.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: b7374884ab90c0b7fca54225029a9d03a1e1c63774317a334bda4e141c3dc9d0
4
- data.tar.gz: f14efe5a80d9c8db745593bfd462ee4db268b1b5c0e4b10b513bd181086652e0
3
+ metadata.gz: 4de21050a409102a97ed7a57ad9a4e3e407ae1c9236ee12bcf56ba065df09674
4
+ data.tar.gz: aa2537d23e5d13baa679133e50d046992a2a31a2b5abdd3ebad5ec1be5b6e745
5
5
  SHA512:
6
- metadata.gz: 20c7c98145f99ae436ed07174c87cf145b3b8b86d8430c8e274bdebcbc15df0b11f74574b8b81c0c1646e299f3b2176691202bcd368f92b8e41a2c024740ee6d
7
- data.tar.gz: 6431ea10562ce748be42951d94b59c13d8aba8eddf7ca97ce6a4bdb6ea46d726a2961031dc52bca748b329cc06a857ee4785bca9f882b2a606b27cafb85a51e0
6
+ metadata.gz: 804ff034798b639ba1c8cc522df79ecdfafa4403ef4fd320c626db053367d6da846dceecc56449197b20fda7cc6dda1b00fbc91e6cdf230c0804ea0ff757d9ca
7
+ data.tar.gz: 4aadd98e8b6d7e7caaaf4a741eb59231612770a733408d9a98ee064bc561d00d3c50ffc6ba2c723277d64d017f831c4fe5dcf26df8a5c3d2be84a14fc7e426b2
data/README.md CHANGED
@@ -1,8 +1,9 @@
1
1
  # AttributesMapper
2
2
 
3
- Welcome to your new gem! In this directory, you'll find the files you need to be able to package up your Ruby library into a gem. Put your Ruby code in the file `lib/attributes/mapper`. To experiment with that code, run `bin/console` for an interactive prompt.
3
+ Builds upon `[json-path-builder](https://github.com/omnitech-solutions/json-path-builder)` to deliver a highly declarative and dynamic mapping of JSON/Hash Attributes
4
4
 
5
- TODO: Delete this and the text above, and describe your gem
5
+ ## Console
6
+ run `irb -r ./dev/setup` for an interactive prompt.
6
7
 
7
8
  ## Installation
8
9
 
@@ -22,7 +23,37 @@ Or install it yourself as:
22
23
 
23
24
  ## Usage
24
25
 
25
- TODO: Write usage instructions here
26
+ ```ruby
27
+ class UserAttributesMapper < AttributesMapper::Builder
28
+ configure do |config|
29
+ config.required_attributes = %i[name email]
30
+ config.optional_attributes = %i[age key]
31
+ config.scopes = { profile: 'user.profile', info: 'user.info' }
32
+ end
33
+
34
+ name { { from: :username, scope: :profile } } # corresponds to path `user.profile.username`
35
+ email { { from: :email, scope: :profile } } # corresponds to path `user.profile.email`
36
+ age { { from: :age, scope: :info } } # corresponds to path `user.info.age`
37
+ key { { from: :key } } # corresponds to path `key`
38
+ end
39
+
40
+ input = { user:
41
+ { profile:
42
+ {
43
+ username: 'Joe Bloggs',
44
+ email: 'joe@email.com'
45
+ },
46
+ info: {
47
+
48
+ age: 23
49
+ }
50
+ },
51
+ key: 'some-value'
52
+ }
53
+
54
+ builder = UserAttributesMapper.new(input).build
55
+ builder.to_h #=> { name: 'Joe Bloggs', email: 'joe@email.com', age: 23, key: 'some-value' }
56
+ ```
26
57
 
27
58
  ## Development
28
59
 
data/dev/setup.rb CHANGED
@@ -10,6 +10,7 @@ require 'active_support/core_ext/object/blank'
10
10
  require 'active_support/core_ext/object/json'
11
11
  require 'active_support/core_ext/enumerable'
12
12
  require 'active_support/configurable'
13
+ require 'rudash'
13
14
 
14
15
  %w[../../lib/attributes_mapper ../../spec/spec_helper].each do |rel_path|
15
16
  require File.expand_path(rel_path, Pathname.new(__FILE__).realpath)
@@ -0,0 +1,67 @@
1
+ module AttributesMapper
2
+ class Builder
3
+ include HasAttributes
4
+
5
+ attr_reader :input
6
+
7
+ def initialize(input)
8
+ transformed_input = if configuration.apply_input_data_transform?
9
+ configuration.apply_input_data_transform_proc.call(input)
10
+ else
11
+ input
12
+ end
13
+
14
+ @input = Rordash::HashUtil.deep_symbolize_keys(transformed_input)
15
+ @mapped_input = {}
16
+ end
17
+
18
+ def build
19
+ @mapped_input = paths_builder.build_for(input).deep_symbolize_keys
20
+ self
21
+ end
22
+
23
+ def to_h
24
+ @mapped_input
25
+ end
26
+
27
+ def paths_builder
28
+ @paths_builder ||= begin
29
+ builder = JsonPath::Builder.new
30
+ if configuration.source_data_wrapper_class?
31
+ builder.with_wrapped_data_class(configuration.source_data_wrapper_class)
32
+ end
33
+ add_paths_to_builder(builder)
34
+ builder
35
+ end
36
+ end
37
+
38
+ private
39
+
40
+ def add_paths_to_builder(builder)
41
+ self.class.each_path_context_key_value_pair do |to, path_attrs|
42
+ params = path_attrs.merge(to: to)
43
+
44
+ if params.key?(SCOPE)
45
+ scope_path = self.class.find_path_by_scope_name(params[SCOPE])
46
+ builder.within(scope_path) { add_path_to_builder(builder, params) }
47
+ else
48
+ add_path_to_builder(builder, params)
49
+ end
50
+ end
51
+ end
52
+
53
+ def add_path_to_builder(builder, path_params)
54
+ builder.from(path_params[:from], **path_params.except(:from, SCOPE))
55
+ end
56
+
57
+ def method_missing(method_name, *arguments, &block)
58
+ return @mapped_input[method_name] if @mapped_input.key?(method_name)
59
+
60
+ super
61
+ end
62
+
63
+ def respond_to_missing?(method_name, include_private = false)
64
+ @mapped_input.key?(method_name) || super
65
+ end
66
+ end
67
+ end
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module AttributesMapper
4
- VERSION = "0.1.0"
4
+ VERSION = "0.1.2"
5
5
  end
@@ -2,11 +2,15 @@
2
2
 
3
3
  require 'rordash'
4
4
  require 'json-path/builder'
5
+ require 'json-path/default_data_wrapper'
6
+ require 'json-path/path_context'
7
+ require 'json-path/path_context_collection'
5
8
 
6
9
  %w[
7
10
  version
8
11
  configuration
9
12
  has_attributes
13
+ builder
10
14
  ].each do |filename|
11
15
  require File.expand_path("../attributes-mapper/#{filename}", Pathname.new(__FILE__).realpath)
12
16
  end
@@ -0,0 +1,66 @@
1
+ # frozen_string_literal: true
2
+
3
+ module AttributesMapper
4
+ RSpec.describe Builder do
5
+ let(:subject_class) do
6
+ Class.new(described_class) do
7
+ configure do |config|
8
+ config.required_attributes = %i[name email]
9
+ config.optional_attributes = %i[age key]
10
+ config.scopes = { profile: 'user.profile', info: 'user.info' }
11
+ end
12
+
13
+ name { { from: :username, scope: :profile } }
14
+ email { { from: :email, scope: :profile } }
15
+ age { { from: :age, scope: :info } }
16
+ key { { from: :key } }
17
+ end
18
+ end
19
+
20
+ let(:name) { 'Joe Bloggs' }
21
+ let(:email) { 'joe@email.com' }
22
+ let(:age) { 23 }
23
+ let(:value) { 'some-value' }
24
+ let(:input) { { user: { profile: { username: name, email: email }, info: { age: age } }, key: value } }
25
+
26
+ subject(:built_builder) { subject_class.new(input).build }
27
+
28
+ describe '#build' do
29
+ it 'handles simple mappings' do
30
+ expect(built_builder.key).to eql(value)
31
+ end
32
+
33
+ it 'handle nested paths via declared scopes' do
34
+ expect(built_builder.name).to eql(name)
35
+ expect(built_builder.email).to eql(email)
36
+ expect(built_builder.age).to eql(age)
37
+ end
38
+ end
39
+
40
+ describe '#to_h' do
41
+ it 'maps input to the specified paths' do
42
+ expect(built_builder.to_h).to eq({ name: name, email: email, age: age, key: value })
43
+ end
44
+ end
45
+
46
+ describe '#method_missing' do
47
+ it 'returns the value of a mapped key' do
48
+ expect(built_builder.key).to eq(value)
49
+ end
50
+
51
+ it 'raises an error when the key does not exist' do
52
+ expect { built_builder.baz }.to raise_error(NoMethodError)
53
+ end
54
+ end
55
+
56
+ describe '#respond_to_missing?' do
57
+ it 'returns true when the key exists' do
58
+ expect(built_builder.respond_to?(:name)).to be true
59
+ end
60
+
61
+ it 'returns false when the key does not exist' do
62
+ expect(built_builder.respond_to?(:baz)).to be false
63
+ end
64
+ end
65
+ end
66
+ end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: attributes-mapper
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.0
4
+ version: 0.1.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - Desmond O'Leary
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2023-03-02 00:00:00.000000000 Z
11
+ date: 2023-03-03 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: json-path-builder
@@ -117,11 +117,13 @@ files:
117
117
  - bin/rubocop
118
118
  - bin/setup
119
119
  - dev/setup.rb
120
+ - lib/attributes-mapper/builder.rb
120
121
  - lib/attributes-mapper/configuration.rb
121
122
  - lib/attributes-mapper/has_attributes.rb
122
123
  - lib/attributes-mapper/version.rb
123
124
  - lib/attributes_mapper.rb
124
125
  - sig/attributes/mapper.rbs
126
+ - spec/attributes-mapper/builder_spec.rb
125
127
  - spec/attributes-mapper/configuration_spec.rb
126
128
  - spec/attributes-mapper/has_attributes_spec.rb
127
129
  - spec/attributes_mapper_spec.rb