attributes-mapper 0.1.0 → 0.1.2

Sign up to get free protection for your applications and to get access to all the features.
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