arstotzka 1.0.3 → 1.0.4
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/.circleci/config.yml +19 -8
- data/.gitignore +3 -0
- data/.rubocop.yml +1 -0
- data/.rubocop_todo.yml +6 -3
- data/.yardopts +1 -0
- data/Dockerfile +8 -0
- data/README.md +2 -3
- data/Rakefile +2 -0
- data/arstotzka.gemspec +11 -8
- data/config/yardstick.rb +13 -0
- data/config/yardstick.yml +69 -0
- data/docker-compose.yml +14 -9
- data/lib/arstotzka/builder.rb +72 -0
- data/lib/arstotzka/class_methods.rb +9 -2
- data/lib/arstotzka/crawler.rb +56 -5
- data/lib/arstotzka/fetcher.rb +43 -14
- data/lib/arstotzka/reader.rb +44 -1
- data/lib/arstotzka/type_cast.rb +114 -1
- data/lib/arstotzka/version.rb +1 -1
- data/lib/arstotzka/wrapper.rb +47 -2
- data/spec/integration/readme/arstotzka_spec.rb +41 -0
- data/spec/integration/readme/my_parser_spec.rb +14 -13
- data/spec/integration/yard/arstotzka/crawler_spec.rb +9 -9
- data/spec/integration/yard/arstotzka/fetcher_spec.rb +4 -4
- data/spec/integration/yard/arstotzka/reader_spec.rb +7 -7
- data/spec/integration/yard/arstotzka/type_cast_spec.rb +55 -0
- data/spec/integration/yard/arstotzka/wrapper_spec.rb +30 -14
- data/spec/integration/yard/arstotzka_spec.rb +9 -9
- data/spec/lib/arstotzka/builder_spec.rb +18 -16
- data/spec/lib/arstotzka/crawler_spec.rb +21 -13
- data/spec/lib/arstotzka/fetcher_spec.rb +12 -10
- data/spec/lib/arstotzka/reader_spec.rb +16 -16
- data/spec/lib/arstotzka/wrapper_spec.rb +8 -2
- data/spec/lib/arstotzka_spec.rb +23 -23
- data/spec/support/models/car.rb +10 -0
- data/spec/support/models/car_collector.rb +20 -0
- data/spec/support/models/request.rb +9 -0
- data/spec/support/models/type_caster.rb +13 -0
- data/spec/support/shared_examples/wrapper.rb +2 -2
- metadata +65 -23
- data/spec/integration/readme/default_spec.rb +0 -39
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA1:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: f6434b65a0dc88484fb45965e6c0700978300f24
|
|
4
|
+
data.tar.gz: e91d322f0ad668991927080809a0ba63430814ac
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 5bd3079f38a8f38d95ef74521273f02dc9c40add3c81315d5bde04382fd75f02b017663cca973ed99a17681d9bf6bf509f9df9b79977edf9ab62f29fbccd1291
|
|
7
|
+
data.tar.gz: 8929be5f4f9fae35d4ad87f54b3a60d7a361877c975e04dadbeebb553a5d0888fbb0f0167e00d1c72bd9e308eacd54176041e9b4c8848d029ebfd4addb2bda19
|
data/.circleci/config.yml
CHANGED
|
@@ -2,13 +2,24 @@ version: 2
|
|
|
2
2
|
jobs:
|
|
3
3
|
build:
|
|
4
4
|
docker:
|
|
5
|
-
- image:
|
|
5
|
+
- image: darthjee/circleci_ruby_240:0.1.0
|
|
6
6
|
steps:
|
|
7
7
|
- checkout
|
|
8
|
-
- run:
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
- run:
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
- run:
|
|
8
|
+
- run:
|
|
9
|
+
name: Prepare Coverage Test Report
|
|
10
|
+
command: cc-test-reporter before-build
|
|
11
|
+
- run:
|
|
12
|
+
name: Bundle Install
|
|
13
|
+
command: bundle install
|
|
14
|
+
- run:
|
|
15
|
+
name: RSpec
|
|
16
|
+
command: bundle exec rspec
|
|
17
|
+
- run:
|
|
18
|
+
name: Rubocop
|
|
19
|
+
command: rubocop
|
|
20
|
+
- run:
|
|
21
|
+
name: Coverage Test Report
|
|
22
|
+
command: cc-test-reporter after-build --exit-code $?
|
|
23
|
+
- run:
|
|
24
|
+
name: Yardstick coverage check
|
|
25
|
+
command: bundle exec rake verify_measurements
|
data/.gitignore
CHANGED
data/.rubocop.yml
CHANGED
data/.rubocop_todo.yml
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# This configuration was generated by
|
|
2
2
|
# `rubocop --auto-gen-config`
|
|
3
|
-
# on
|
|
3
|
+
# on 2019-03-07 08:37:15 +0000 using RuboCop version 0.58.1.
|
|
4
4
|
# The point is for the user to remove these configuration records
|
|
5
5
|
# one by one as the offenses are removed from the code base.
|
|
6
6
|
# Note that changes in the inspected code, or installation of new
|
|
@@ -9,5 +9,8 @@
|
|
|
9
9
|
# Offense count: 1
|
|
10
10
|
# Configuration parameters: CountKeywordArgs.
|
|
11
11
|
Metrics/ParameterLists:
|
|
12
|
-
|
|
13
|
-
|
|
12
|
+
Max: 7
|
|
13
|
+
|
|
14
|
+
# Offense count: 46
|
|
15
|
+
RSpec/NestedGroups:
|
|
16
|
+
Max: 5
|
data/.yardopts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
--private --no-private
|
data/Dockerfile
ADDED
data/README.md
CHANGED
|
@@ -37,7 +37,7 @@ Instalation
|
|
|
37
37
|
|
|
38
38
|
Yard Documentation
|
|
39
39
|
-------------------
|
|
40
|
-
https://www.rubydoc.info/gems/arstotzka/
|
|
40
|
+
https://www.rubydoc.info/gems/arstotzka/1.0.4
|
|
41
41
|
|
|
42
42
|
Getting Started
|
|
43
43
|
---------------
|
|
@@ -156,8 +156,7 @@ end
|
|
|
156
156
|
]
|
|
157
157
|
)
|
|
158
158
|
|
|
159
|
-
object.
|
|
160
|
-
#returns 1050.36
|
|
159
|
+
object.total_money # returns 1050.36
|
|
161
160
|
```
|
|
162
161
|
|
|
163
162
|
## Default
|
data/Rakefile
CHANGED
data/arstotzka.gemspec
CHANGED
|
@@ -19,14 +19,17 @@ Gem::Specification.new do |spec|
|
|
|
19
19
|
spec.require_paths = ['lib']
|
|
20
20
|
|
|
21
21
|
spec.add_runtime_dependency 'activesupport', '~> 5.x'
|
|
22
|
-
spec.add_runtime_dependency 'sinclair',
|
|
22
|
+
spec.add_runtime_dependency 'sinclair', '>= 1.1.1'
|
|
23
|
+
|
|
24
|
+
spec.add_development_dependency 'bundler', '~> 1.17.x'
|
|
25
|
+
spec.add_development_dependency 'pry-nav', '~> 0.2.4'
|
|
26
|
+
spec.add_development_dependency 'rake', '>= 12.3.1'
|
|
27
|
+
spec.add_development_dependency 'rspec', '>= 3.8'
|
|
28
|
+
spec.add_development_dependency 'rubocop', '0.58.1'
|
|
29
|
+
spec.add_development_dependency 'rubocop-rspec', '1.30.0'
|
|
30
|
+
spec.add_development_dependency 'simplecov', '~> 0.16.x'
|
|
31
|
+
spec.add_development_dependency 'yard', '>= 0.9.18'
|
|
32
|
+
spec.add_development_dependency 'yardstick', '>= 0.9.9'
|
|
23
33
|
|
|
24
|
-
spec.add_development_dependency 'bundler', '~> 1.6'
|
|
25
|
-
spec.add_development_dependency 'pry-nav'
|
|
26
|
-
spec.add_development_dependency 'rake', '>= 12.3.1'
|
|
27
|
-
spec.add_development_dependency 'rspec', '>= 3.7'
|
|
28
|
-
spec.add_development_dependency 'rubocop'
|
|
29
34
|
spec.add_development_dependency 'safe_attribute_assignment'
|
|
30
|
-
spec.add_development_dependency 'simplecov'
|
|
31
|
-
spec.add_development_dependency 'yard'
|
|
32
35
|
end
|
data/config/yardstick.rb
ADDED
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require 'yardstick/rake/measurement'
|
|
4
|
+
require 'yardstick/rake/verify'
|
|
5
|
+
require 'yaml'
|
|
6
|
+
|
|
7
|
+
options = YAML.load_file('config/yardstick.yml')
|
|
8
|
+
|
|
9
|
+
Yardstick::Rake::Measurement.new(:yardstick_measure, options) do |measurement|
|
|
10
|
+
measurement.output = 'measurement/report.txt'
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
Yardstick::Rake::Verify.new(:verify_measurements, options)
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
threshold: 100
|
|
2
|
+
require_exact_threshold: false
|
|
3
|
+
rules:
|
|
4
|
+
ApiTag::Presence:
|
|
5
|
+
enabled: true
|
|
6
|
+
exclude: []
|
|
7
|
+
ApiTag::Inclusion:
|
|
8
|
+
enabled: true
|
|
9
|
+
exclude: []
|
|
10
|
+
ApiTag::ProtectedMethod:
|
|
11
|
+
enabled: true
|
|
12
|
+
exclude: []
|
|
13
|
+
ApiTag::PrivateMethod:
|
|
14
|
+
enabled: true
|
|
15
|
+
exclude: []
|
|
16
|
+
ExampleTag:
|
|
17
|
+
enabled: true
|
|
18
|
+
exclude: []
|
|
19
|
+
ReturnTag:
|
|
20
|
+
enabled: true
|
|
21
|
+
exclude:
|
|
22
|
+
- Arstotzka::Builder#attr_names
|
|
23
|
+
- Arstotzka::Builder#json_name
|
|
24
|
+
- Arstotzka::Builder#path
|
|
25
|
+
- Arstotzka::Builder#full_path
|
|
26
|
+
- Arstotzka::Builder#cached
|
|
27
|
+
- Arstotzka::Crawler#post_process
|
|
28
|
+
- Arstotzka::Crawler#path
|
|
29
|
+
- Arstotzka::Crawler#case_type
|
|
30
|
+
- Arstotzka::Crawler#compact
|
|
31
|
+
- Arstotzka::Crawler#default
|
|
32
|
+
- Arstotzka::Fetcher#path
|
|
33
|
+
- Arstotzka::Fetcher#hash
|
|
34
|
+
- Arstotzka::Fetcher#instance
|
|
35
|
+
- Arstotzka::Reader#path
|
|
36
|
+
- Arstotzka::Reader#case_type
|
|
37
|
+
- Arstotzka::Reader#change_case
|
|
38
|
+
- Arstotzka::Wrapper#clazz
|
|
39
|
+
- Arstotzka::Wrapper#type
|
|
40
|
+
Summary::Presence:
|
|
41
|
+
enabled: true
|
|
42
|
+
exclude:
|
|
43
|
+
- Arstotzka::Builder#attr_names
|
|
44
|
+
- Arstotzka::Builder#json_name
|
|
45
|
+
- Arstotzka::Builder#path
|
|
46
|
+
- Arstotzka::Builder#full_path
|
|
47
|
+
- Arstotzka::Builder#cached
|
|
48
|
+
- Arstotzka::Crawler#post_process
|
|
49
|
+
- Arstotzka::Crawler#path
|
|
50
|
+
- Arstotzka::Crawler#case_type
|
|
51
|
+
- Arstotzka::Crawler#compact
|
|
52
|
+
- Arstotzka::Crawler#default
|
|
53
|
+
- Arstotzka::Fetcher#path
|
|
54
|
+
- Arstotzka::Fetcher#hash
|
|
55
|
+
- Arstotzka::Fetcher#instance
|
|
56
|
+
- Arstotzka::Reader#path
|
|
57
|
+
- Arstotzka::Reader#case_type
|
|
58
|
+
- Arstotzka::Reader#change_case
|
|
59
|
+
- Arstotzka::Wrapper#clazz
|
|
60
|
+
- Arstotzka::Wrapper#type
|
|
61
|
+
Summary::Length:
|
|
62
|
+
enabled: true
|
|
63
|
+
exclude: []
|
|
64
|
+
Summary::Delimiter:
|
|
65
|
+
enabled: true
|
|
66
|
+
exclude: []
|
|
67
|
+
Summary::SingleLine:
|
|
68
|
+
enabled: true
|
|
69
|
+
exclude: []
|
data/docker-compose.yml
CHANGED
|
@@ -1,18 +1,23 @@
|
|
|
1
|
-
version: '
|
|
1
|
+
version: '3'
|
|
2
2
|
services:
|
|
3
3
|
base: &base
|
|
4
|
-
image:
|
|
5
|
-
working_dir: /home/app/
|
|
4
|
+
image: arstotzka
|
|
5
|
+
working_dir: /home/app/app
|
|
6
6
|
volumes:
|
|
7
|
-
- .:/home/app/
|
|
8
|
-
- arstotzka_gems_2_4_0:/usr/local/bundle
|
|
7
|
+
- .:/home/app/app
|
|
9
8
|
|
|
10
|
-
|
|
9
|
+
base_build:
|
|
10
|
+
<<: *base
|
|
11
|
+
build: .
|
|
12
|
+
command: echo done
|
|
11
13
|
|
|
12
14
|
arstotzka:
|
|
13
15
|
<<: *base
|
|
14
16
|
container_name: arstotzka
|
|
15
|
-
|
|
17
|
+
depends_on: [base_build]
|
|
18
|
+
command: /bin/bash -c 'rspec'
|
|
16
19
|
|
|
17
|
-
|
|
18
|
-
|
|
20
|
+
test_all:
|
|
21
|
+
<<: *base
|
|
22
|
+
depends_on: [base_build]
|
|
23
|
+
command: /bin/bash -c 'rspec && yard && rake yardstick_measure && rake verify_measurements'
|
data/lib/arstotzka/builder.rb
CHANGED
|
@@ -4,6 +4,8 @@ module Arstotzka
|
|
|
4
4
|
# Class responsible to orchestrate the addtion of method that will
|
|
5
5
|
# crawl the hash for value
|
|
6
6
|
#
|
|
7
|
+
# @api private
|
|
8
|
+
#
|
|
7
9
|
# @example
|
|
8
10
|
# class MyModel
|
|
9
11
|
# attr_reader :json
|
|
@@ -48,6 +50,7 @@ module Arstotzka
|
|
|
48
50
|
type: :none
|
|
49
51
|
}.freeze
|
|
50
52
|
|
|
53
|
+
# Returns new instance of Arstotzka::Builder
|
|
51
54
|
# @param attr_names [Array] list of attributes to be fetched from the hash/json
|
|
52
55
|
# @param clazz [Class] class to receive the methods
|
|
53
56
|
# @param path [String/Symbol] path of hash attributes to find the root
|
|
@@ -89,26 +92,71 @@ module Arstotzka
|
|
|
89
92
|
|
|
90
93
|
private
|
|
91
94
|
|
|
95
|
+
# @private
|
|
92
96
|
attr_reader :attr_names, :json_name, :path, :full_path, :cached
|
|
93
97
|
|
|
98
|
+
# @private
|
|
99
|
+
#
|
|
100
|
+
# Initialize methods list
|
|
101
|
+
#
|
|
102
|
+
# @return nil
|
|
94
103
|
def init
|
|
95
104
|
attr_names.each do |attr|
|
|
96
105
|
add_attr(attr)
|
|
97
106
|
end
|
|
98
107
|
end
|
|
99
108
|
|
|
109
|
+
# @private
|
|
110
|
+
#
|
|
111
|
+
# builds the complete key path to fetch value
|
|
112
|
+
#
|
|
113
|
+
# @param [String/Symbol] attribute name of the method / attribute
|
|
114
|
+
#
|
|
115
|
+
# @return [String] the keys path
|
|
100
116
|
def real_path(attribute)
|
|
101
117
|
full_path || [path, attribute].compact.join('.')
|
|
102
118
|
end
|
|
103
119
|
|
|
120
|
+
# @private
|
|
121
|
+
#
|
|
122
|
+
# Fetch class to wrap resulting value
|
|
123
|
+
#
|
|
124
|
+
# after fetching the value, when wrapper_clazz returns
|
|
125
|
+
# a Class object, the value will be wrapped with
|
|
126
|
+
# +wrapper_clazz.new(value)+
|
|
127
|
+
#
|
|
128
|
+
# @return [Class] the class to wrap the resulting value
|
|
129
|
+
#
|
|
130
|
+
# @see Arstotzka::Wrapper
|
|
104
131
|
def wrapper_clazz
|
|
105
132
|
options[:class]
|
|
106
133
|
end
|
|
107
134
|
|
|
135
|
+
# @private
|
|
136
|
+
#
|
|
137
|
+
# Fetches the case of the keys
|
|
138
|
+
#
|
|
139
|
+
# case types can be
|
|
140
|
+
# - lower_camel: keys in the hash are lowerCamelCase
|
|
141
|
+
# - upper_camel: keys in the hash are UpperCamelCase
|
|
142
|
+
# - snake: keys in the hash are snake_case
|
|
143
|
+
#
|
|
144
|
+
# @return [Symbol/String] defined case_type
|
|
145
|
+
#
|
|
146
|
+
# @see Arstotzka::Reader
|
|
108
147
|
def case_type
|
|
109
148
|
options[:case]
|
|
110
149
|
end
|
|
111
150
|
|
|
151
|
+
# @private
|
|
152
|
+
#
|
|
153
|
+
# Options needed by fetcher
|
|
154
|
+
#
|
|
155
|
+
# @param [String/Symbol] attribute name of the method / attribute
|
|
156
|
+
#
|
|
157
|
+
# @return [Hash] options
|
|
158
|
+
#
|
|
159
|
+
# @see Arstotzka::Fetcher
|
|
112
160
|
def fetcher_options(attribute)
|
|
113
161
|
options.slice(:compact, :after, :type, :flatten, :default).merge(
|
|
114
162
|
clazz: wrapper_clazz,
|
|
@@ -117,10 +165,27 @@ module Arstotzka
|
|
|
117
165
|
)
|
|
118
166
|
end
|
|
119
167
|
|
|
168
|
+
# @private
|
|
169
|
+
#
|
|
170
|
+
# Add method to the list of methods to be built
|
|
171
|
+
#
|
|
172
|
+
# @param [String/Symbol] attribute name of method / attribute
|
|
173
|
+
#
|
|
174
|
+
# @return nil
|
|
175
|
+
#
|
|
176
|
+
# @see Sinclair
|
|
120
177
|
def add_attr(attribute)
|
|
121
178
|
add_method attribute, (cached ? cached_fetcher(attribute) : attr_fetcher(attribute)).to_s
|
|
122
179
|
end
|
|
123
180
|
|
|
181
|
+
# Returns the code needed to initialize fetcher
|
|
182
|
+
#
|
|
183
|
+
# @param [String/Symbol] attribute name of method / attribute
|
|
184
|
+
#
|
|
185
|
+
# @return [String] code
|
|
186
|
+
#
|
|
187
|
+
# @see Sinclair
|
|
188
|
+
# @see Artotzka::Fetcher
|
|
124
189
|
def attr_fetcher(attribute)
|
|
125
190
|
<<-CODE
|
|
126
191
|
::Arstotzka::Fetcher.new(
|
|
@@ -129,6 +194,13 @@ module Arstotzka
|
|
|
129
194
|
CODE
|
|
130
195
|
end
|
|
131
196
|
|
|
197
|
+
# Returns the code needed to initialize a fetche and cache it
|
|
198
|
+
#
|
|
199
|
+
# @param [String/Symbol] attribute name of method / attribute
|
|
200
|
+
#
|
|
201
|
+
# @return [String] code
|
|
202
|
+
#
|
|
203
|
+
# @see #attr_fetcher
|
|
132
204
|
def cached_fetcher(attribute)
|
|
133
205
|
<<-CODE
|
|
134
206
|
@#{attribute} ||= #{attr_fetcher(attribute)}
|
|
@@ -4,7 +4,12 @@ module Arstotzka
|
|
|
4
4
|
# As Arstotzka extends ActiveSupport::Concern, Arstotzka::ClassMethods define
|
|
5
5
|
# methods that will be available when defining a class that includes Arstotka
|
|
6
6
|
module ClassMethods
|
|
7
|
-
|
|
7
|
+
private
|
|
8
|
+
|
|
9
|
+
# @api public
|
|
10
|
+
# @!visibility public
|
|
11
|
+
#
|
|
12
|
+
# Expose a field from the json/hash as a method
|
|
8
13
|
#
|
|
9
14
|
# @example
|
|
10
15
|
# class MyModel
|
|
@@ -30,9 +35,11 @@ module Arstotzka
|
|
|
30
35
|
# instance.age # returns 20
|
|
31
36
|
# instance.cars # returns 2
|
|
32
37
|
#
|
|
38
|
+
# @return nil
|
|
39
|
+
#
|
|
33
40
|
# @see Builder Arstotzka::Builder
|
|
34
41
|
# @see
|
|
35
|
-
# https://www.rubydoc.info/gems/activesupport/5.
|
|
42
|
+
# https://www.rubydoc.info/gems/activesupport/5.2.2/ActiveSupport/Concern
|
|
36
43
|
# ActiveSupport::Concern
|
|
37
44
|
def expose(*attr_names, **options)
|
|
38
45
|
options = Builder::DEFAULT_OPTIONS.merge(options.symbolize_keys)
|
data/lib/arstotzka/crawler.rb
CHANGED
|
@@ -2,6 +2,9 @@
|
|
|
2
2
|
|
|
3
3
|
module Arstotzka
|
|
4
4
|
# Crawl a hash through the path of keys
|
|
5
|
+
#
|
|
6
|
+
# @api private
|
|
7
|
+
#
|
|
5
8
|
# @example
|
|
6
9
|
# crawler = Arstotzka::Crawler.new(%w(person information first_name))
|
|
7
10
|
# hash = {
|
|
@@ -13,6 +16,8 @@ module Arstotzka
|
|
|
13
16
|
# }
|
|
14
17
|
# crawler.value(hash) # returns 'John'
|
|
15
18
|
class Crawler
|
|
19
|
+
# Creates a new instance of Crawler
|
|
20
|
+
#
|
|
16
21
|
# @param path [Array] path of keys to be crawled
|
|
17
22
|
# @param case_type [Symbol] case type of the keys
|
|
18
23
|
# - snake: snake_cased keys
|
|
@@ -29,9 +34,7 @@ module Arstotzka
|
|
|
29
34
|
@post_process = block || proc { |value| value }
|
|
30
35
|
end
|
|
31
36
|
|
|
32
|
-
#
|
|
33
|
-
# returning the final value
|
|
34
|
-
#
|
|
37
|
+
# Crawls into the hash looking for all keys in the given path
|
|
35
38
|
# @overload value(hash)
|
|
36
39
|
# @return [Object] value fetched from the last Hash#fetch call using the last part
|
|
37
40
|
# of path
|
|
@@ -91,8 +94,33 @@ module Arstotzka
|
|
|
91
94
|
|
|
92
95
|
private
|
|
93
96
|
|
|
97
|
+
# @private
|
|
94
98
|
attr_reader :post_process, :path, :case_type, :compact, :default
|
|
95
99
|
|
|
100
|
+
# Fetch the value from hash by crawling the keys
|
|
101
|
+
#
|
|
102
|
+
# The crawling is similar to fetching values in a chain
|
|
103
|
+
# <code>
|
|
104
|
+
# { a: { b: 10 } }.fetch(:a).fetch(:b)
|
|
105
|
+
# </code>
|
|
106
|
+
# with added features like accessing string and
|
|
107
|
+
# symbol keys alike, wrapping the values in new objects,
|
|
108
|
+
# post processing the values, treating arrays as collection
|
|
109
|
+
# of hashes, etc...
|
|
110
|
+
#
|
|
111
|
+
# Once the value is found (with final key), it is wrapped
|
|
112
|
+
#
|
|
113
|
+
# If value found in any step (except finel step) and this
|
|
114
|
+
# is an Array, then next interations will happen with it
|
|
115
|
+
# element of the array, returning an array of results
|
|
116
|
+
#
|
|
117
|
+
# @param [Hash] hash the hash to be crawled
|
|
118
|
+
# @param [Integer] index the index of the key to be used in the current iteration
|
|
119
|
+
#
|
|
120
|
+
# @return [Object] value found at the lest key after transformation
|
|
121
|
+
#
|
|
122
|
+
# @see #wrap
|
|
123
|
+
# @see #crawl_array
|
|
96
124
|
def crawl(hash, index = 0)
|
|
97
125
|
return wrap(hash) if reader.ended?(index)
|
|
98
126
|
return crawl_array(hash, index) if hash.is_a?(Array)
|
|
@@ -100,6 +128,11 @@ module Arstotzka
|
|
|
100
128
|
crawl(reader.read(hash, index), index + 1)
|
|
101
129
|
end
|
|
102
130
|
|
|
131
|
+
# @private
|
|
132
|
+
#
|
|
133
|
+
# Builds a hash reader
|
|
134
|
+
#
|
|
135
|
+
# @return [Arstotzka::Reader] Object responsible for extracting values out of the hash
|
|
103
136
|
def reader
|
|
104
137
|
@reader ||= Arstotzka::Reader.new(
|
|
105
138
|
path: path,
|
|
@@ -107,10 +140,28 @@ module Arstotzka
|
|
|
107
140
|
)
|
|
108
141
|
end
|
|
109
142
|
|
|
110
|
-
|
|
111
|
-
|
|
143
|
+
# @private
|
|
144
|
+
#
|
|
145
|
+
# Wrap value with final calls
|
|
146
|
+
#
|
|
147
|
+
# The final value can be wrapped in a class, or processed
|
|
148
|
+
# via instance method call
|
|
149
|
+
#
|
|
150
|
+
# @param [Object] value the value to be wrapped
|
|
151
|
+
# @return [Object] the post-processed / wraped value
|
|
152
|
+
def wrap(value)
|
|
153
|
+
post_process.call(value)
|
|
112
154
|
end
|
|
113
155
|
|
|
156
|
+
# @private
|
|
157
|
+
#
|
|
158
|
+
# Iterate over array applying #crawl over each element
|
|
159
|
+
#
|
|
160
|
+
# @param [Array] array the array of hashes be crawled
|
|
161
|
+
# @param [Integer] index the index of the key to be used in the current iteration
|
|
162
|
+
#
|
|
163
|
+
# @return [Array] the new array with the individual values returned
|
|
164
|
+
# @see #crawl
|
|
114
165
|
def crawl_array(array, index)
|
|
115
166
|
array.map { |j| value(j, index) }.tap do |a|
|
|
116
167
|
a.compact! if compact
|
data/lib/arstotzka/fetcher.rb
CHANGED
|
@@ -1,11 +1,15 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
3
|
module Arstotzka
|
|
4
|
+
# @api private
|
|
5
|
+
#
|
|
4
6
|
# Class responsible for orquestrating the fetch value from the hash
|
|
5
7
|
# and post-processing it
|
|
6
8
|
class Fetcher
|
|
7
9
|
include Sinclair::OptionsParser
|
|
8
10
|
|
|
11
|
+
# Creates an instance of Artotzka::Fetcher
|
|
12
|
+
#
|
|
9
13
|
# @param hash [Hash] Hash to be crawled for value
|
|
10
14
|
# @param instance [Object] object whose methods will be called after for processing
|
|
11
15
|
# @param path [String/Symbol] complete path for fetching the value from hash
|
|
@@ -17,8 +21,12 @@ module Arstotzka
|
|
|
17
21
|
@options = options
|
|
18
22
|
end
|
|
19
23
|
|
|
20
|
-
# Crawls the hash for the value
|
|
21
|
-
#
|
|
24
|
+
# Crawls the hash for the value
|
|
25
|
+
#
|
|
26
|
+
# After the crawling, final transformation is applied on
|
|
27
|
+
# the final result (collection not value)
|
|
28
|
+
#
|
|
29
|
+
# @return [Object] The final value found and transformed
|
|
22
30
|
#
|
|
23
31
|
# @example
|
|
24
32
|
# class Transaction
|
|
@@ -73,33 +81,54 @@ module Arstotzka
|
|
|
73
81
|
|
|
74
82
|
private
|
|
75
83
|
|
|
84
|
+
# @private
|
|
76
85
|
attr_reader :path, :hash, :instance
|
|
77
86
|
|
|
78
87
|
delegate :after, :flatten, to: :options_object
|
|
79
88
|
delegate :wrap, to: :wrapper
|
|
80
89
|
|
|
90
|
+
# @private
|
|
91
|
+
#
|
|
92
|
+
# Returns an instance of Aristotzka::Craler
|
|
93
|
+
#
|
|
94
|
+
# craler will be responsible to crawl the hash for
|
|
95
|
+
# the final return
|
|
96
|
+
#
|
|
97
|
+
# @return [Arstotzka::Crawler] the crawler object
|
|
81
98
|
def crawler
|
|
82
|
-
@crawler ||=
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
Arstotzka::Crawler.new(crawler_options) do |value|
|
|
87
|
-
wrap(value)
|
|
88
|
-
end
|
|
99
|
+
@crawler ||=
|
|
100
|
+
Arstotzka::Crawler.new(crawler_options) do |value|
|
|
101
|
+
wrap(value)
|
|
102
|
+
end
|
|
89
103
|
end
|
|
90
104
|
|
|
105
|
+
# @private
|
|
106
|
+
#
|
|
107
|
+
# Hash for crawler initialization
|
|
108
|
+
#
|
|
109
|
+
# @return [Hash]
|
|
110
|
+
#
|
|
111
|
+
# @see #crawler
|
|
91
112
|
def crawler_options
|
|
92
113
|
options.slice(:case_type, :compact, :default).merge(path: path)
|
|
93
114
|
end
|
|
94
115
|
|
|
116
|
+
# @private
|
|
117
|
+
#
|
|
118
|
+
# Wrapper responsible for wrapping the value found
|
|
119
|
+
#
|
|
120
|
+
# @return [Arstotzka::Wrapper] the wrapper
|
|
95
121
|
def wrapper
|
|
96
|
-
@wrapper ||=
|
|
97
|
-
end
|
|
98
|
-
|
|
99
|
-
def build_wrapper
|
|
100
|
-
Arstotzka::Wrapper.new(wrapper_options)
|
|
122
|
+
@wrapper ||= Arstotzka::Wrapper.new(wrapper_options)
|
|
101
123
|
end
|
|
102
124
|
|
|
125
|
+
# @private
|
|
126
|
+
#
|
|
127
|
+
# Hash for wrapper initialization
|
|
128
|
+
#
|
|
129
|
+
# @return [Hash]
|
|
130
|
+
#
|
|
131
|
+
# @see #wrapper
|
|
103
132
|
def wrapper_options
|
|
104
133
|
options.slice(:clazz, :type)
|
|
105
134
|
end
|