tarvit-helpers 0.0.16 → 0.0.17
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 +4 -4
- data/VERSION +1 -1
- data/lib/tarvit-helpers/modules/hash_presenter/cached_hash_presenter.rb +15 -0
- data/lib/tarvit-helpers/modules/hash_presenter/custom_hash_presenter.rb +66 -0
- data/lib/tarvit-helpers/modules/hash_presenter/observable_hash_presenter.rb +14 -0
- data/lib/tarvit-helpers/modules/hash_presenter/simple_hash_presenter.rb +59 -0
- data/lib/tarvit-helpers/modules/hash_presenter.rb +5 -139
- data/spec/modules/hash_presenter_spec.rb +24 -24
- data/tarvit-helpers.gemspec +6 -2
- metadata +5 -1
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: f05ecb11ce055643c43b40cc820e3c66f999374f
|
4
|
+
data.tar.gz: d94035c4af11f06e9f0d16ad037cb8e09582d247
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 36b61567a2c03af8f0c6223d5f41fee45a3d447a23fe0b940bb57fa8ded14c868aa1fbc30a65e9f30e50f6a2296df22ab3dfdae121409fd65b3e68711321945a
|
7
|
+
data.tar.gz: 45eb5df5f82f596c64d894d2016cf1e094bb64717c37b792b96d45d95fefb5b601c94ea7c7774494fd3604fefdd2eff4fe30c5c8962af7d4f2a858cf0b1e497a
|
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
0.0.
|
1
|
+
0.0.17
|
@@ -0,0 +1,66 @@
|
|
1
|
+
module TarvitHelpers
|
2
|
+
module HashPresenter
|
3
|
+
|
4
|
+
class Custom < Cached
|
5
|
+
attr_reader :_rules_holder
|
6
|
+
|
7
|
+
def initialize(hash, levels=[], rules_holder=nil, &rules)
|
8
|
+
super(hash, levels)
|
9
|
+
@_rules_holder = rules_holder || _init_rules_holder
|
10
|
+
_init_rules
|
11
|
+
rules.call(_rules_holder) if rules
|
12
|
+
end
|
13
|
+
|
14
|
+
def _current_path(method_name)
|
15
|
+
_levels + [ method_name ]
|
16
|
+
end
|
17
|
+
|
18
|
+
protected
|
19
|
+
|
20
|
+
def _hash_value(method_name)
|
21
|
+
value = super
|
22
|
+
rule = _rules_holder.rule_for(_path(method_name))
|
23
|
+
rule ? rule.value_transformer.call(value, self) : value
|
24
|
+
end
|
25
|
+
|
26
|
+
def _new_level_presenter(value, method_name)
|
27
|
+
self.class.new(value, _path(method_name), _rules_holder)
|
28
|
+
end
|
29
|
+
|
30
|
+
def _init_rules; end
|
31
|
+
|
32
|
+
def _init_rules_holder
|
33
|
+
RulesHolder.new
|
34
|
+
end
|
35
|
+
|
36
|
+
def _accessor_method?(method_name)
|
37
|
+
super(method_name) || _rules_holder.rules.map{|r| r.path.last }.include?(method_name)
|
38
|
+
end
|
39
|
+
|
40
|
+
alias_method :_rules, :_rules_holder
|
41
|
+
|
42
|
+
class RulesHolder
|
43
|
+
attr_reader :rules
|
44
|
+
|
45
|
+
def initialize
|
46
|
+
@rules = []
|
47
|
+
end
|
48
|
+
|
49
|
+
def when(path, &_transform_value)
|
50
|
+
self.rules << Rule.new(path, _transform_value)
|
51
|
+
end
|
52
|
+
|
53
|
+
def rule_for(path)
|
54
|
+
rules.find{|r| r.path == path }
|
55
|
+
end
|
56
|
+
end
|
57
|
+
|
58
|
+
class Rule
|
59
|
+
attr_reader :path, :value_transformer
|
60
|
+
def initialize(path, value_transformer)
|
61
|
+
@path, @value_transformer = path, value_transformer
|
62
|
+
end
|
63
|
+
end
|
64
|
+
end
|
65
|
+
end
|
66
|
+
end
|
@@ -0,0 +1,59 @@
|
|
1
|
+
module TarvitHelpers
|
2
|
+
module HashPresenter
|
3
|
+
|
4
|
+
class Simple
|
5
|
+
require 'active_support/core_ext/string'
|
6
|
+
|
7
|
+
attr_reader :_hash, :_levels
|
8
|
+
|
9
|
+
def initialize(hash, levels=[])
|
10
|
+
@_hash = _prepare_keys(hash)
|
11
|
+
@_levels = levels
|
12
|
+
end
|
13
|
+
|
14
|
+
def method_missing(m, *args)
|
15
|
+
return _value(m) if _accessor_method?(m)
|
16
|
+
super
|
17
|
+
end
|
18
|
+
|
19
|
+
protected
|
20
|
+
|
21
|
+
def _value(method_name)
|
22
|
+
_transform_value(method_name, _hash_value(method_name))
|
23
|
+
end
|
24
|
+
|
25
|
+
def _hash_value(method_name)
|
26
|
+
_hash[method_name]
|
27
|
+
end
|
28
|
+
|
29
|
+
def _transform_value(method_name, value)
|
30
|
+
return value.map{|key| _transform_value(method_name, key) } if value.is_a?(Array)
|
31
|
+
value.is_a?(Hash) ? _new_level_presenter(value, method_name) : value
|
32
|
+
end
|
33
|
+
|
34
|
+
def _accessor_method?(method_name)
|
35
|
+
self._hash.keys.include?(method_name)
|
36
|
+
end
|
37
|
+
|
38
|
+
def _key_to_method(key)
|
39
|
+
key.to_s.gsub(/\s+/, ?_).underscore.to_sym
|
40
|
+
end
|
41
|
+
|
42
|
+
def _prepare_keys(hash)
|
43
|
+
res = hash.map do |k ,v|
|
44
|
+
[ _key_to_method(k), v ]
|
45
|
+
end
|
46
|
+
Hash[res]
|
47
|
+
end
|
48
|
+
|
49
|
+
def _path(key)
|
50
|
+
_levels + [ key ]
|
51
|
+
end
|
52
|
+
|
53
|
+
def _new_level_presenter(value, method_name)
|
54
|
+
self.class.new(value, _path(method_name))
|
55
|
+
end
|
56
|
+
|
57
|
+
end
|
58
|
+
end
|
59
|
+
end
|
@@ -1,5 +1,9 @@
|
|
1
1
|
module TarvitHelpers
|
2
2
|
module HashPresenter
|
3
|
+
require_relative '../modules/hash_presenter/simple_hash_presenter'
|
4
|
+
require_relative '../modules/hash_presenter/cached_hash_presenter'
|
5
|
+
require_relative '../modules/hash_presenter/observable_hash_presenter'
|
6
|
+
require_relative '../modules/hash_presenter/custom_hash_presenter'
|
3
7
|
|
4
8
|
def self.present(hash, option = :cached )
|
5
9
|
raise ArgumentError.new("#{ hash.class } is not a Hash") unless hash.is_a?(Hash)
|
@@ -7,146 +11,8 @@ module TarvitHelpers
|
|
7
11
|
end
|
8
12
|
|
9
13
|
def self.factory
|
10
|
-
{ cached:
|
14
|
+
{ cached: Cached, observable: Observable }
|
11
15
|
end
|
12
16
|
|
13
|
-
class SimpleHashPresenter
|
14
|
-
require 'active_support/core_ext/string'
|
15
|
-
|
16
|
-
attr_reader :_hash, :_levels
|
17
|
-
|
18
|
-
def initialize(hash, levels=[])
|
19
|
-
@_hash = _prepare_keys(hash)
|
20
|
-
@_levels = levels
|
21
|
-
end
|
22
|
-
|
23
|
-
def method_missing(m, *args)
|
24
|
-
return _value(m) if _accessor_method?(m)
|
25
|
-
super
|
26
|
-
end
|
27
|
-
|
28
|
-
protected
|
29
|
-
|
30
|
-
def _value(method_name)
|
31
|
-
_transform_value(method_name, _hash_value(method_name))
|
32
|
-
end
|
33
|
-
|
34
|
-
def _hash_value(method_name)
|
35
|
-
_hash[method_name]
|
36
|
-
end
|
37
|
-
|
38
|
-
def _transform_value(method_name, value)
|
39
|
-
return value.map{|key| _transform_value(method_name, key) } if value.is_a?(Array)
|
40
|
-
value.is_a?(Hash) ? _new_level_presenter(value, method_name) : value
|
41
|
-
end
|
42
|
-
|
43
|
-
def _accessor_method?(method_name)
|
44
|
-
self._hash.keys.include?(method_name)
|
45
|
-
end
|
46
|
-
|
47
|
-
def _key_to_method(key)
|
48
|
-
key.to_s.gsub(/\s+/, ?_).underscore.to_sym
|
49
|
-
end
|
50
|
-
|
51
|
-
def _prepare_keys(hash)
|
52
|
-
res = hash.map do |k ,v|
|
53
|
-
[ _key_to_method(k), v ]
|
54
|
-
end
|
55
|
-
Hash[res]
|
56
|
-
end
|
57
|
-
|
58
|
-
def _path(key)
|
59
|
-
_levels + [ key ]
|
60
|
-
end
|
61
|
-
|
62
|
-
def _new_level_presenter(value, method_name)
|
63
|
-
self.class.new(value, _path(method_name))
|
64
|
-
end
|
65
|
-
|
66
|
-
end
|
67
|
-
|
68
|
-
class CachedHashPresenter < SimpleHashPresenter
|
69
|
-
def initialize(hash, levels=[])
|
70
|
-
super
|
71
|
-
@cache = {}
|
72
|
-
end
|
73
|
-
|
74
|
-
def _value(method_name)
|
75
|
-
@cache[method_name] ||= super
|
76
|
-
end
|
77
|
-
end
|
78
|
-
|
79
|
-
class ObservableHashPresenter < SimpleHashPresenter
|
80
|
-
def initialize(hash, levels=[])
|
81
|
-
@_hash = hash
|
82
|
-
@_levels = levels
|
83
|
-
end
|
84
|
-
|
85
|
-
def _hash
|
86
|
-
_prepare_keys(@_hash)
|
87
|
-
end
|
88
|
-
end
|
89
|
-
|
90
|
-
class CustomHashPresenter < CachedHashPresenter
|
91
|
-
attr_reader :_rules_holder
|
92
|
-
|
93
|
-
def initialize(hash, levels=[], rules_holder=nil, &rules)
|
94
|
-
super(hash, levels)
|
95
|
-
@_rules_holder = rules_holder || _init_rules_holder
|
96
|
-
_init_rules
|
97
|
-
rules.call(_rules_holder) if rules
|
98
|
-
end
|
99
|
-
|
100
|
-
def _current_path(method_name)
|
101
|
-
_levels + [ method_name ]
|
102
|
-
end
|
103
|
-
|
104
|
-
protected
|
105
|
-
|
106
|
-
def _hash_value(method_name)
|
107
|
-
value = super
|
108
|
-
rule = _rules_holder.rule_for(_path(method_name))
|
109
|
-
rule ? rule.value_transformer.call(value, self) : value
|
110
|
-
end
|
111
|
-
|
112
|
-
def _new_level_presenter(value, method_name)
|
113
|
-
self.class.new(value, _path(method_name), _rules_holder)
|
114
|
-
end
|
115
|
-
|
116
|
-
def _init_rules; end
|
117
|
-
|
118
|
-
def _init_rules_holder
|
119
|
-
RulesHolder.new
|
120
|
-
end
|
121
|
-
|
122
|
-
def _accessor_method?(method_name)
|
123
|
-
super(method_name) || _rules_holder.rules.map{|r| r.path.last }.include?(method_name)
|
124
|
-
end
|
125
|
-
|
126
|
-
alias_method :_rules, :_rules_holder
|
127
|
-
|
128
|
-
class RulesHolder
|
129
|
-
attr_reader :rules
|
130
|
-
|
131
|
-
def initialize
|
132
|
-
@rules = []
|
133
|
-
end
|
134
|
-
|
135
|
-
def when(path, &_transform_value)
|
136
|
-
self.rules << Rule.new(path, _transform_value)
|
137
|
-
end
|
138
|
-
|
139
|
-
def rule_for(path)
|
140
|
-
rules.find{|r| r.path == path }
|
141
|
-
end
|
142
|
-
end
|
143
|
-
|
144
|
-
class Rule
|
145
|
-
attr_reader :path, :value_transformer
|
146
|
-
def initialize(path, value_transformer)
|
147
|
-
@path, @value_transformer = path, value_transformer
|
148
|
-
end
|
149
|
-
end
|
150
|
-
end
|
151
17
|
end
|
152
18
|
end
|
@@ -34,16 +34,16 @@ module BaseHashPresenterTest
|
|
34
34
|
end
|
35
35
|
end
|
36
36
|
|
37
|
-
describe HashPresenter::
|
37
|
+
describe HashPresenter::Simple do
|
38
38
|
|
39
39
|
extend BaseHashPresenterTest
|
40
|
-
test_presenter(HashPresenter::
|
40
|
+
test_presenter(HashPresenter::Simple)
|
41
41
|
|
42
42
|
context 'Special Behavior' do
|
43
43
|
|
44
44
|
it 'should not depend on an attribute object' do
|
45
45
|
original = { a: 2 }
|
46
|
-
hp = HashPresenter::
|
46
|
+
hp = HashPresenter::Simple.new(original)
|
47
47
|
|
48
48
|
expect(hp.a).to eq(2)
|
49
49
|
|
@@ -53,22 +53,22 @@ describe HashPresenter::SimpleHashPresenter do
|
|
53
53
|
end
|
54
54
|
|
55
55
|
it 'should regenerate method result for a nested hash' do
|
56
|
-
hp = HashPresenter::
|
56
|
+
hp = HashPresenter::Simple.new(a: { b: 1 })
|
57
57
|
expect(hp.a.object_id).to_not eq(hp.a.object_id)
|
58
58
|
end
|
59
59
|
end
|
60
60
|
end
|
61
61
|
|
62
|
-
describe HashPresenter::
|
62
|
+
describe HashPresenter::Cached do
|
63
63
|
|
64
64
|
extend BaseHashPresenterTest
|
65
|
-
test_presenter(HashPresenter::
|
65
|
+
test_presenter(HashPresenter::Cached)
|
66
66
|
|
67
67
|
context 'Special Behavior' do
|
68
68
|
|
69
69
|
it 'should not depend on an attribute object' do
|
70
70
|
original = { a: 2 }
|
71
|
-
hp = HashPresenter::
|
71
|
+
hp = HashPresenter::Cached.new(original)
|
72
72
|
|
73
73
|
expect(hp.a).to eq(2)
|
74
74
|
|
@@ -78,23 +78,23 @@ describe HashPresenter::CachedHashPresenter do
|
|
78
78
|
end
|
79
79
|
|
80
80
|
it 'should not calculate result for a nested hash twice' do
|
81
|
-
hp = HashPresenter::
|
81
|
+
hp = HashPresenter::Cached.new(a: { b: 1 })
|
82
82
|
expect(hp.a.object_id).to eq(hp.a.object_id)
|
83
83
|
end
|
84
84
|
end
|
85
85
|
end
|
86
86
|
|
87
87
|
|
88
|
-
describe HashPresenter::
|
88
|
+
describe HashPresenter::Observable do
|
89
89
|
|
90
90
|
extend BaseHashPresenterTest
|
91
|
-
test_presenter(HashPresenter::
|
91
|
+
test_presenter(HashPresenter::Observable)
|
92
92
|
|
93
93
|
context 'Special Behavior' do
|
94
94
|
|
95
95
|
it 'should observe an attribute object' do
|
96
96
|
original = { a: 2 }
|
97
|
-
hp = HashPresenter::
|
97
|
+
hp = HashPresenter::Observable.new(original)
|
98
98
|
|
99
99
|
expect(hp.a).to eq(2)
|
100
100
|
|
@@ -112,16 +112,16 @@ describe HashPresenter::ObservableHashPresenter do
|
|
112
112
|
end
|
113
113
|
|
114
114
|
it 'should regenerate method result for a nested hash' do
|
115
|
-
hp = HashPresenter::
|
115
|
+
hp = HashPresenter::Observable.new(a: { b: 1 })
|
116
116
|
expect(hp.a.object_id).to_not eq(hp.a.object_id)
|
117
117
|
end
|
118
118
|
end
|
119
119
|
end
|
120
120
|
|
121
121
|
|
122
|
-
describe HashPresenter::
|
122
|
+
describe HashPresenter::Custom do
|
123
123
|
extend BaseHashPresenterTest
|
124
|
-
test_presenter(HashPresenter::
|
124
|
+
test_presenter(HashPresenter::Custom)
|
125
125
|
|
126
126
|
context 'Special Behavior' do
|
127
127
|
before :each do
|
@@ -141,7 +141,7 @@ describe HashPresenter::CustomHashPresenter do
|
|
141
141
|
end
|
142
142
|
|
143
143
|
it 'should customize presenter' do
|
144
|
-
presenter = HashPresenter::
|
144
|
+
presenter = HashPresenter::Custom.new(@hash) do |rules|
|
145
145
|
rules.when([ :user, :date ]) do |value|
|
146
146
|
Date.parse(value)
|
147
147
|
end
|
@@ -158,7 +158,7 @@ describe HashPresenter::CustomHashPresenter do
|
|
158
158
|
end
|
159
159
|
|
160
160
|
it 'should declare nested presenters' do
|
161
|
-
presenter = HashPresenter::
|
161
|
+
presenter = HashPresenter::Custom.new(@hash) do |rules|
|
162
162
|
|
163
163
|
rules.when([ :user, :date ]) do |value|
|
164
164
|
Date.parse(value)
|
@@ -166,7 +166,7 @@ describe HashPresenter::CustomHashPresenter do
|
|
166
166
|
|
167
167
|
rules.when([ :user, :posts ])do |posts|
|
168
168
|
posts.map do |post|
|
169
|
-
HashPresenter::
|
169
|
+
HashPresenter::Custom.new(post) do |post_rules|
|
170
170
|
post_rules.when([ :title ]){|title| title.upcase }
|
171
171
|
end
|
172
172
|
end
|
@@ -185,16 +185,14 @@ describe HashPresenter::CustomHashPresenter do
|
|
185
185
|
:id => 1,
|
186
186
|
:name => :director,
|
187
187
|
collections: [
|
188
|
-
{
|
189
|
-
|
190
|
-
:name => :test_collection,
|
191
|
-
}
|
188
|
+
{ :id => 42, :name => :test_collection },
|
189
|
+
{ :id => 24, :name => :best_collection },
|
192
190
|
]
|
193
191
|
}
|
194
192
|
]
|
195
193
|
}
|
196
194
|
|
197
|
-
class AccountsPresenter < HashPresenter::
|
195
|
+
class AccountsPresenter < HashPresenter::Custom
|
198
196
|
|
199
197
|
def _init_rules
|
200
198
|
rules = _rules
|
@@ -227,6 +225,8 @@ describe HashPresenter::CustomHashPresenter do
|
|
227
225
|
expect(account.website).to eq('www.johndoe.com/director')
|
228
226
|
expect(account.collections[0].name).to eq('TestCollection')
|
229
227
|
expect(account.collections[0].folder).to eq('folders/TestCollection')
|
228
|
+
expect(account.collections[1].name).to eq('BestCollection')
|
229
|
+
expect(account.collections[1].folder).to eq('folders/BestCollection')
|
230
230
|
end
|
231
231
|
|
232
232
|
end
|
@@ -248,12 +248,12 @@ describe HashPresenter do
|
|
248
248
|
|
249
249
|
it 'should get an observable presenter' do
|
250
250
|
hp = HashPresenter.present({ }, :observable)
|
251
|
-
expect(hp).to be_a(HashPresenter::
|
251
|
+
expect(hp).to be_a(HashPresenter::Observable)
|
252
252
|
end
|
253
253
|
|
254
254
|
it 'should get a cached presenter' do
|
255
255
|
hp = HashPresenter.present({ }, :cached)
|
256
|
-
expect(hp).to be_a(HashPresenter::
|
256
|
+
expect(hp).to be_a(HashPresenter::Cached)
|
257
257
|
end
|
258
258
|
|
259
259
|
end
|
data/tarvit-helpers.gemspec
CHANGED
@@ -2,11 +2,11 @@
|
|
2
2
|
# DO NOT EDIT THIS FILE DIRECTLY
|
3
3
|
# Instead, edit Jeweler::Tasks in Rakefile, and run 'rake gemspec'
|
4
4
|
# -*- encoding: utf-8 -*-
|
5
|
-
# stub: tarvit-helpers 0.0.
|
5
|
+
# stub: tarvit-helpers 0.0.17 ruby lib
|
6
6
|
|
7
7
|
Gem::Specification.new do |s|
|
8
8
|
s.name = "tarvit-helpers"
|
9
|
-
s.version = "0.0.
|
9
|
+
s.version = "0.0.17"
|
10
10
|
|
11
11
|
s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
|
12
12
|
s.require_paths = ["lib"]
|
@@ -30,6 +30,10 @@ Gem::Specification.new do |s|
|
|
30
30
|
"lib/tarvit-helpers/extensions/counter.rb",
|
31
31
|
"lib/tarvit-helpers/modules/conditional_logger.rb",
|
32
32
|
"lib/tarvit-helpers/modules/hash_presenter.rb",
|
33
|
+
"lib/tarvit-helpers/modules/hash_presenter/cached_hash_presenter.rb",
|
34
|
+
"lib/tarvit-helpers/modules/hash_presenter/custom_hash_presenter.rb",
|
35
|
+
"lib/tarvit-helpers/modules/hash_presenter/observable_hash_presenter.rb",
|
36
|
+
"lib/tarvit-helpers/modules/hash_presenter/simple_hash_presenter.rb",
|
33
37
|
"lib/tarvit-helpers/modules/non_shared_accessors.rb",
|
34
38
|
"lib/tarvit-helpers/modules/recursive_loader.rb",
|
35
39
|
"lib/tarvit-helpers/modules/simple_crypt.rb",
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: tarvit-helpers
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0.
|
4
|
+
version: 0.0.17
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Vitaly Tarasenko
|
@@ -113,6 +113,10 @@ files:
|
|
113
113
|
- lib/tarvit-helpers/extensions/counter.rb
|
114
114
|
- lib/tarvit-helpers/modules/conditional_logger.rb
|
115
115
|
- lib/tarvit-helpers/modules/hash_presenter.rb
|
116
|
+
- lib/tarvit-helpers/modules/hash_presenter/cached_hash_presenter.rb
|
117
|
+
- lib/tarvit-helpers/modules/hash_presenter/custom_hash_presenter.rb
|
118
|
+
- lib/tarvit-helpers/modules/hash_presenter/observable_hash_presenter.rb
|
119
|
+
- lib/tarvit-helpers/modules/hash_presenter/simple_hash_presenter.rb
|
116
120
|
- lib/tarvit-helpers/modules/non_shared_accessors.rb
|
117
121
|
- lib/tarvit-helpers/modules/recursive_loader.rb
|
118
122
|
- lib/tarvit-helpers/modules/simple_crypt.rb
|