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 +4 -4
- data/README.md +34 -3
- data/dev/setup.rb +1 -0
- data/lib/attributes-mapper/builder.rb +67 -0
- data/lib/attributes-mapper/version.rb +1 -1
- data/lib/attributes_mapper.rb +4 -0
- data/spec/attributes-mapper/builder_spec.rb +66 -0
- metadata +4 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 4de21050a409102a97ed7a57ad9a4e3e407ae1c9236ee12bcf56ba065df09674
|
4
|
+
data.tar.gz: aa2537d23e5d13baa679133e50d046992a2a31a2b5abdd3ebad5ec1be5b6e745
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 804ff034798b639ba1c8cc522df79ecdfafa4403ef4fd320c626db053367d6da846dceecc56449197b20fda7cc6dda1b00fbc91e6cdf230c0804ea0ff757d9ca
|
7
|
+
data.tar.gz: 4aadd98e8b6d7e7caaaf4a741eb59231612770a733408d9a98ee064bc561d00d3c50ffc6ba2c723277d64d017f831c4fe5dcf26df8a5c3d2be84a14fc7e426b2
|
data/README.md
CHANGED
@@ -1,8 +1,9 @@
|
|
1
1
|
# AttributesMapper
|
2
2
|
|
3
|
-
|
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
|
-
|
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
|
-
|
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
|
data/lib/attributes_mapper.rb
CHANGED
@@ -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.
|
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-
|
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
|