arstotzka 1.0.4 → 1.1.0
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 +3 -0
- data/.rubocop.yml +3 -0
- data/.rubocop_todo.yml +6 -4
- data/README.md +61 -64
- data/config/yardstick.yml +14 -26
- data/lib/arstotzka/base.rb +27 -0
- data/lib/arstotzka/builder.rb +24 -83
- data/lib/arstotzka/class_methods.rb +3 -3
- data/lib/arstotzka/crawler.rb +33 -29
- data/lib/arstotzka/fetcher.rb +11 -23
- data/lib/arstotzka/options.rb +72 -0
- data/lib/arstotzka/reader.rb +32 -23
- data/lib/arstotzka/type_cast.rb +3 -3
- data/lib/arstotzka/version.rb +1 -1
- data/lib/arstotzka/wrapper.rb +18 -10
- data/lib/arstotzka.rb +4 -2
- data/scripts/check_readme.sh +6 -0
- data/spec/integration/yard/arstotzka/builder_spec.rb +11 -11
- data/spec/integration/yard/arstotzka/crawler_spec.rb +7 -7
- data/spec/integration/yard/arstotzka/fetcher_spec.rb +3 -3
- data/spec/integration/yard/arstotzka/reader_spec.rb +5 -5
- data/spec/integration/yard/arstotzka/wrapper_spec.rb +6 -6
- data/spec/lib/arstotzka/builder_spec.rb +7 -7
- data/spec/lib/arstotzka/crawler_spec.rb +28 -28
- data/spec/lib/arstotzka/fetcher_spec.rb +9 -9
- data/spec/lib/arstotzka/options_spec.rb +208 -0
- data/spec/lib/arstotzka/reader_spec.rb +15 -15
- data/spec/lib/arstotzka/wrapper_spec.rb +13 -13
- data/spec/lib/arstotzka_spec.rb +2 -2
- data/spec/support/models/arstotzka/dummy.rb +4 -4
- data/spec/support/models/collector.rb +3 -1
- data/spec/support/models/star_gazer.rb +1 -1
- metadata +7 -2
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA1:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 74d1946cebd9e40fa273fc644a478e809ce9d888
|
|
4
|
+
data.tar.gz: 66abec44e1e8090d5507c8f4c59532dce3e8be03
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 931eb74bb1e15412c7927c613204dbac3d48dc1ca6f3d81d58c941540ccf23ed530a19c4f8b1214ef06ba0f878d44e5e28cc6b55f3a32c0930123336d4fe3b43
|
|
7
|
+
data.tar.gz: fac8783602cc90be4933d9dce2f2fe5b6e24fd284ec2c53925ee75cd5cb5895aa62a1de5a40acdef5e158c66cc174df8fe3390ebfacacd7460f5d39c705830f6
|
data/.circleci/config.yml
CHANGED
data/.rubocop.yml
CHANGED
data/.rubocop_todo.yml
CHANGED
|
@@ -1,15 +1,17 @@
|
|
|
1
1
|
# This configuration was generated by
|
|
2
2
|
# `rubocop --auto-gen-config`
|
|
3
|
-
# on 2019-03-
|
|
3
|
+
# on 2019-03-11 11:14:54 +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
|
|
7
7
|
# versions of RuboCop, may require this file to be generated again.
|
|
8
8
|
|
|
9
9
|
# Offense count: 1
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
10
|
+
|
|
11
|
+
# Offense count: 1
|
|
12
|
+
RSpec/AnyInstance:
|
|
13
|
+
Exclude:
|
|
14
|
+
- 'spec/lib/arstotzka/options_spec.rb'
|
|
13
15
|
|
|
14
16
|
# Offense count: 46
|
|
15
17
|
RSpec/NestedGroups:
|
data/README.md
CHANGED
|
@@ -3,6 +3,7 @@ Arstotzka
|
|
|
3
3
|
[](https://codeclimate.com/github/darthjee/arstotzka)
|
|
4
4
|
[](https://codeclimate.com/github/darthjee/arstotzka/coverage)
|
|
5
5
|
[](https://codeclimate.com/github/darthjee/arstotzka)
|
|
6
|
+
[](https://badge.fury.io/rb/arstotzka)
|
|
6
7
|
|
|
7
8
|

|
|
8
9
|
|
|
@@ -21,72 +22,71 @@ Instalation
|
|
|
21
22
|
1. Add Arstotzka to your `Gemfile` and `bundle install`:
|
|
22
23
|
- Install it
|
|
23
24
|
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
25
|
+
```ruby
|
|
26
|
+
gem install arstotzka
|
|
27
|
+
```
|
|
27
28
|
|
|
28
|
-
|
|
29
|
+
- Or add Arstotka to you `Gemfile` and `bundle install`
|
|
29
30
|
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
31
|
+
```ruby
|
|
32
|
+
gem 'arstotzka'
|
|
33
|
+
```
|
|
33
34
|
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
35
|
+
```bash
|
|
36
|
+
bundle install arstotzka
|
|
37
|
+
```
|
|
37
38
|
|
|
38
39
|
Yard Documentation
|
|
39
40
|
-------------------
|
|
40
|
-
https://www.rubydoc.info/gems/arstotzka/1.0
|
|
41
|
+
https://www.rubydoc.info/gems/arstotzka/1.1.0
|
|
41
42
|
|
|
42
43
|
Getting Started
|
|
43
44
|
---------------
|
|
44
45
|
1. Include in a class that you want to wrap a json/hash
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
46
|
+
|
|
47
|
+
```ruby
|
|
48
|
+
class MyParser
|
|
49
|
+
include Arstotzka
|
|
50
|
+
end
|
|
51
|
+
```
|
|
49
52
|
|
|
50
53
|
2. Declare the keys you want to crawl
|
|
51
|
-
```ruby
|
|
52
|
-
class MyParser
|
|
53
|
-
include Arstotzka
|
|
54
54
|
|
|
55
|
-
|
|
56
|
-
|
|
55
|
+
```ruby
|
|
56
|
+
class MyParser
|
|
57
|
+
include Arstotzka
|
|
58
|
+
|
|
59
|
+
expose :id
|
|
60
|
+
expose :name, :age, path: :person
|
|
57
61
|
|
|
58
|
-
|
|
62
|
+
attr_reader :json
|
|
59
63
|
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
end
|
|
64
|
+
def initialize(json = {})
|
|
65
|
+
@json = json
|
|
63
66
|
end
|
|
67
|
+
end
|
|
64
68
|
|
|
65
|
-
|
|
69
|
+
```
|
|
66
70
|
|
|
67
|
-
|
|
71
|
+
and let it fetch values from your hash
|
|
68
72
|
|
|
69
73
|
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
74
|
+
```ruby
|
|
75
|
+
MyParser.new(
|
|
76
|
+
id: 10,
|
|
77
|
+
age: 22
|
|
78
|
+
person: {
|
|
79
|
+
name: 'Robert',
|
|
73
80
|
age: 22
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
}
|
|
78
|
-
)
|
|
79
|
-
|
|
80
|
-
object.name
|
|
81
|
-
#returns 'Robert'
|
|
82
|
-
```
|
|
81
|
+
}
|
|
82
|
+
)
|
|
83
|
+
```
|
|
83
84
|
|
|
84
|
-
|
|
85
|
+
this is usefull when trying to fetch data from hashes missing nodes
|
|
85
86
|
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
```
|
|
87
|
+
```ruby
|
|
88
|
+
MyParser.new.name # returns nil
|
|
89
|
+
```
|
|
90
90
|
|
|
91
91
|
3. fully customise the way you crawl / fetch the information with [Options](#options)
|
|
92
92
|
|
|
@@ -98,7 +98,7 @@ Options
|
|
|
98
98
|
- json: method that contains the hash to be parsed (json by default)
|
|
99
99
|
- full_path: full path to fetch the value (empty by default)
|
|
100
100
|
- cached: indicator that once the value has been fetched, it should be cached (false by default)
|
|
101
|
-
-
|
|
101
|
+
- klass: class to be used when wrapping the final value
|
|
102
102
|
- compact: indicator telling to ignore nil values inside array (false by default)
|
|
103
103
|
- flatten: indicator telling that to flattern the resulting array (false by default)
|
|
104
104
|
- after: name of a method to be called after with the resulting value
|
|
@@ -143,20 +143,20 @@ end
|
|
|
143
143
|
```
|
|
144
144
|
|
|
145
145
|
```ruby
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
146
|
+
object = MyParser.new(
|
|
147
|
+
accounts: [
|
|
148
|
+
{ balance: '$ 1000.50', type: 'checking' },
|
|
149
|
+
{ balance: '$ 150.10', type: 'savings' },
|
|
150
|
+
{ balance: '$ -100.24', type: 'checking' }
|
|
151
|
+
],
|
|
152
|
+
loans: [
|
|
153
|
+
{ value: '$ 300.50', bank: 'the_bank' },
|
|
154
|
+
{ value: '$ 150.10', type: 'the_other_bank' },
|
|
155
|
+
{ value: '$ 100.24', type: 'the_same_bank' }
|
|
156
|
+
]
|
|
157
|
+
)
|
|
158
|
+
|
|
159
|
+
object.total_money # returns 1050.36
|
|
160
160
|
```
|
|
161
161
|
|
|
162
162
|
## Default
|
|
@@ -175,7 +175,7 @@ class StarGazer
|
|
|
175
175
|
include Arstotzka
|
|
176
176
|
|
|
177
177
|
expose :favorite_star, full_path: 'universe.star',
|
|
178
|
-
default: { name: 'Sun' },
|
|
178
|
+
default: { name: 'Sun' }, klass: ::Star
|
|
179
179
|
|
|
180
180
|
attr_reader :json
|
|
181
181
|
|
|
@@ -186,14 +186,11 @@ end
|
|
|
186
186
|
|
|
187
187
|
```
|
|
188
188
|
|
|
189
|
-
|
|
190
189
|
```ruby
|
|
191
190
|
star_gazer = StarGazer.new
|
|
192
191
|
|
|
193
|
-
star_gazer.favorite_star.name
|
|
194
|
-
#returns "Sun"
|
|
192
|
+
star_gazer.favorite_star.name # returns "Sun"
|
|
195
193
|
|
|
196
|
-
star_gazer.favorite_star.class
|
|
197
|
-
#returns Star
|
|
194
|
+
star_gazer.favorite_star.class # returns Star
|
|
198
195
|
```
|
|
199
196
|
|
data/config/yardstick.yml
CHANGED
|
@@ -20,44 +20,32 @@ rules:
|
|
|
20
20
|
enabled: true
|
|
21
21
|
exclude:
|
|
22
22
|
- Arstotzka::Builder#attr_names
|
|
23
|
+
- Arstotzka::Builder#options
|
|
23
24
|
- Arstotzka::Builder#json_name
|
|
24
|
-
- Arstotzka::Builder#path
|
|
25
|
-
- Arstotzka::Builder#full_path
|
|
26
|
-
- Arstotzka::Builder#cached
|
|
27
25
|
- Arstotzka::Crawler#post_process
|
|
28
|
-
- Arstotzka::Crawler#
|
|
29
|
-
- Arstotzka::
|
|
30
|
-
- Arstotzka::Crawler#compact
|
|
31
|
-
- Arstotzka::Crawler#default
|
|
32
|
-
- Arstotzka::Fetcher#path
|
|
26
|
+
- Arstotzka::Crawler#options
|
|
27
|
+
- Arstotzka::Fetcher#keys
|
|
33
28
|
- Arstotzka::Fetcher#hash
|
|
34
29
|
- Arstotzka::Fetcher#instance
|
|
35
|
-
- Arstotzka::
|
|
36
|
-
- Arstotzka::Reader#
|
|
37
|
-
- Arstotzka::Reader#
|
|
38
|
-
- Arstotzka::Wrapper#
|
|
39
|
-
- Arstotzka::Wrapper#type
|
|
30
|
+
- Arstotzka::Fetcher#options
|
|
31
|
+
- Arstotzka::Reader#keys
|
|
32
|
+
- Arstotzka::Reader#options
|
|
33
|
+
- Arstotzka::Wrapper#options
|
|
40
34
|
Summary::Presence:
|
|
41
35
|
enabled: true
|
|
42
36
|
exclude:
|
|
43
37
|
- Arstotzka::Builder#attr_names
|
|
38
|
+
- Arstotzka::Builder#options
|
|
44
39
|
- Arstotzka::Builder#json_name
|
|
45
|
-
- Arstotzka::Builder#path
|
|
46
|
-
- Arstotzka::Builder#full_path
|
|
47
|
-
- Arstotzka::Builder#cached
|
|
48
40
|
- Arstotzka::Crawler#post_process
|
|
49
|
-
- Arstotzka::Crawler#
|
|
50
|
-
- Arstotzka::
|
|
51
|
-
- Arstotzka::Crawler#compact
|
|
52
|
-
- Arstotzka::Crawler#default
|
|
53
|
-
- Arstotzka::Fetcher#path
|
|
41
|
+
- Arstotzka::Crawler#options
|
|
42
|
+
- Arstotzka::Fetcher#keys
|
|
54
43
|
- Arstotzka::Fetcher#hash
|
|
55
44
|
- Arstotzka::Fetcher#instance
|
|
56
|
-
- Arstotzka::
|
|
57
|
-
- Arstotzka::Reader#
|
|
58
|
-
- Arstotzka::Reader#
|
|
59
|
-
- Arstotzka::Wrapper#
|
|
60
|
-
- Arstotzka::Wrapper#type
|
|
45
|
+
- Arstotzka::Fetcher#options
|
|
46
|
+
- Arstotzka::Reader#keys
|
|
47
|
+
- Arstotzka::Reader#options
|
|
48
|
+
- Arstotzka::Wrapper#options
|
|
61
49
|
Summary::Length:
|
|
62
50
|
enabled: true
|
|
63
51
|
exclude: []
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Arstotzka
|
|
4
|
+
# @api private
|
|
5
|
+
#
|
|
6
|
+
# Common code to be used by classes
|
|
7
|
+
module Base
|
|
8
|
+
private
|
|
9
|
+
|
|
10
|
+
# Sets the @options object
|
|
11
|
+
#
|
|
12
|
+
# @overload options=(options_hash={})
|
|
13
|
+
# @param options_hash [Hash] options
|
|
14
|
+
#
|
|
15
|
+
# @overload options=(options)
|
|
16
|
+
# @param options [Arstotzka::Options] options object
|
|
17
|
+
#
|
|
18
|
+
# @return [Arstotzka::Options]
|
|
19
|
+
def options=(options)
|
|
20
|
+
@options = if options.is_a?(Hash)
|
|
21
|
+
Options.new(options)
|
|
22
|
+
else
|
|
23
|
+
options
|
|
24
|
+
end
|
|
25
|
+
end
|
|
26
|
+
end
|
|
27
|
+
end
|
data/lib/arstotzka/builder.rb
CHANGED
|
@@ -21,13 +21,13 @@ module Arstotzka
|
|
|
21
21
|
# 'cars' => 2.0
|
|
22
22
|
# )
|
|
23
23
|
#
|
|
24
|
-
# options = Arstotzka::
|
|
24
|
+
# options = Arstotzka::Options.new(full_path: 'name.first')
|
|
25
25
|
# builder = Arstotzka::Builder.new([ :first_name ], MyModel, options)
|
|
26
26
|
# builder.build
|
|
27
27
|
#
|
|
28
28
|
# instance.first_name # returns 'John'
|
|
29
29
|
#
|
|
30
|
-
# options = Arstotzka::
|
|
30
|
+
# options = Arstotzka::Options.new(type: :integer)
|
|
31
31
|
# builder = Arstotzka::Builder.new([ :age, :cars ], MyModel, options)
|
|
32
32
|
# builder.build
|
|
33
33
|
#
|
|
@@ -36,64 +36,34 @@ module Arstotzka
|
|
|
36
36
|
#
|
|
37
37
|
# @see https://www.rubydoc.info/gems/sinclair Sinclair
|
|
38
38
|
class Builder < Sinclair
|
|
39
|
-
|
|
40
|
-
json: :json,
|
|
41
|
-
path: nil,
|
|
42
|
-
full_path: nil,
|
|
43
|
-
cached: false,
|
|
44
|
-
after: false,
|
|
45
|
-
case: :lower_camel,
|
|
46
|
-
class: nil,
|
|
47
|
-
compact: false,
|
|
48
|
-
default: nil,
|
|
49
|
-
flatten: false,
|
|
50
|
-
type: :none
|
|
51
|
-
}.freeze
|
|
52
|
-
|
|
39
|
+
include Base
|
|
53
40
|
# Returns new instance of Arstotzka::Builder
|
|
41
|
+
#
|
|
54
42
|
# @param attr_names [Array] list of attributes to be fetched from the hash/json
|
|
55
43
|
# @param clazz [Class] class to receive the methods
|
|
56
|
-
#
|
|
57
|
-
#
|
|
58
|
-
# @
|
|
59
|
-
#
|
|
60
|
-
#
|
|
61
|
-
#
|
|
62
|
-
#
|
|
63
|
-
#
|
|
64
|
-
# @
|
|
65
|
-
#
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
# @option options [Boolean] compact: {Crawler} flag to apply Array#compact thus
|
|
70
|
-
# removing nil results
|
|
71
|
-
# @option options [Class] class: {Fetcher} option thatwhen passed, wraps the result in an
|
|
72
|
-
# instance of the given class
|
|
73
|
-
# @option options [String/Symbol] after: {Fetcher} option with the name of the method to be
|
|
74
|
-
# called once the value is fetched for mapping the value
|
|
75
|
-
# @option options [Boolean] flatten: {Fetcher} flag to aplly Array#flatten thus
|
|
76
|
-
# avoing nested arrays
|
|
77
|
-
# @option options [String/Symbol] type: {Fetcher} option declaring the type of the returned
|
|
78
|
-
# value (to use casting)
|
|
79
|
-
# - integer
|
|
80
|
-
# - string
|
|
81
|
-
# - float
|
|
82
|
-
def initialize(attr_names, clazz, json:, path:, full_path:, cached:, **options)
|
|
83
|
-
super(clazz, options)
|
|
44
|
+
# (using {https://www.rubydoc.info/gems/sinclair Sinclair})
|
|
45
|
+
#
|
|
46
|
+
# @overload initialize(attr_names, clazz, options_hash={})
|
|
47
|
+
# @param options_hash [Hash] hash containing extra options
|
|
48
|
+
#
|
|
49
|
+
# @overload initialize(attr_names, clazz, options)
|
|
50
|
+
# @param options [Arstotzka::Options] options of initialization object
|
|
51
|
+
#
|
|
52
|
+
# @see https://www.rubydoc.info/gems/sinclair Sinclair
|
|
53
|
+
# @see Arstotzka::Options
|
|
54
|
+
def initialize(attr_names, clazz, options = {})
|
|
55
|
+
super(clazz)
|
|
56
|
+
self.options = options
|
|
84
57
|
|
|
85
58
|
@attr_names = attr_names
|
|
86
|
-
@path = path
|
|
87
|
-
@full_path = full_path
|
|
88
|
-
@cached = cached
|
|
89
|
-
@json_name = json
|
|
90
59
|
init
|
|
91
60
|
end
|
|
92
61
|
|
|
93
62
|
private
|
|
94
63
|
|
|
95
64
|
# @private
|
|
96
|
-
attr_reader :attr_names, :
|
|
65
|
+
attr_reader :attr_names, :options
|
|
66
|
+
delegate :json_name, :path, :full_path, :cached, to: :options
|
|
97
67
|
|
|
98
68
|
# @private
|
|
99
69
|
#
|
|
@@ -117,37 +87,6 @@ module Arstotzka
|
|
|
117
87
|
full_path || [path, attribute].compact.join('.')
|
|
118
88
|
end
|
|
119
89
|
|
|
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
|
|
131
|
-
def wrapper_clazz
|
|
132
|
-
options[:class]
|
|
133
|
-
end
|
|
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
|
|
147
|
-
def case_type
|
|
148
|
-
options[:case]
|
|
149
|
-
end
|
|
150
|
-
|
|
151
90
|
# @private
|
|
152
91
|
#
|
|
153
92
|
# Options needed by fetcher
|
|
@@ -158,9 +97,7 @@ module Arstotzka
|
|
|
158
97
|
#
|
|
159
98
|
# @see Arstotzka::Fetcher
|
|
160
99
|
def fetcher_options(attribute)
|
|
161
|
-
options.slice(:compact, :after, :type, :flatten, :default).merge(
|
|
162
|
-
clazz: wrapper_clazz,
|
|
163
|
-
case_type: case_type,
|
|
100
|
+
options.to_h.slice(:klass, :case, :compact, :after, :type, :flatten, :default).merge(
|
|
164
101
|
path: real_path(attribute)
|
|
165
102
|
)
|
|
166
103
|
end
|
|
@@ -178,6 +115,10 @@ module Arstotzka
|
|
|
178
115
|
add_method attribute, (cached ? cached_fetcher(attribute) : attr_fetcher(attribute)).to_s
|
|
179
116
|
end
|
|
180
117
|
|
|
118
|
+
def json_name
|
|
119
|
+
options.json
|
|
120
|
+
end
|
|
121
|
+
|
|
181
122
|
# Returns the code needed to initialize fetcher
|
|
182
123
|
#
|
|
183
124
|
# @param [String/Symbol] attribute name of method / attribute
|
|
@@ -35,14 +35,14 @@ module Arstotzka
|
|
|
35
35
|
# instance.age # returns 20
|
|
36
36
|
# instance.cars # returns 2
|
|
37
37
|
#
|
|
38
|
-
# @return
|
|
38
|
+
# @return [Array<Sinclair::MethodDefinition>]
|
|
39
39
|
#
|
|
40
40
|
# @see Builder Arstotzka::Builder
|
|
41
41
|
# @see
|
|
42
42
|
# https://www.rubydoc.info/gems/activesupport/5.2.2/ActiveSupport/Concern
|
|
43
43
|
# ActiveSupport::Concern
|
|
44
|
-
def expose(*attr_names, **
|
|
45
|
-
options =
|
|
44
|
+
def expose(*attr_names, **options_hash)
|
|
45
|
+
options = Options.new(options_hash.symbolize_keys)
|
|
46
46
|
Builder.new(attr_names, self, options).build
|
|
47
47
|
end
|
|
48
48
|
end
|
data/lib/arstotzka/crawler.rb
CHANGED
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
3
|
module Arstotzka
|
|
4
|
-
# Crawl a hash through the
|
|
4
|
+
# Crawl a hash through the keys of keys
|
|
5
5
|
#
|
|
6
6
|
# @api private
|
|
7
7
|
#
|
|
8
8
|
# @example
|
|
9
|
-
# crawler = Arstotzka::Crawler.new(%w(person information first_name))
|
|
9
|
+
# crawler = Arstotzka::Crawler.new(keys: %w(person information first_name))
|
|
10
10
|
# hash = {
|
|
11
11
|
# person: {
|
|
12
12
|
# 'information' => {
|
|
@@ -16,31 +16,37 @@ module Arstotzka
|
|
|
16
16
|
# }
|
|
17
17
|
# crawler.value(hash) # returns 'John'
|
|
18
18
|
class Crawler
|
|
19
|
+
include Base
|
|
20
|
+
|
|
19
21
|
# Creates a new instance of Crawler
|
|
20
22
|
#
|
|
21
|
-
# @param path [Array] path of keys to be crawled
|
|
22
|
-
# @param case_type [Symbol] case type of the keys
|
|
23
|
-
# - snake: snake_cased keys
|
|
24
|
-
# - lower_camel: lowerCamelCased keys
|
|
25
|
-
# - upper_camel: UperCamelCased keys
|
|
26
|
-
# @param compact [Boolean] flag signallying if nil values should be removed of an array
|
|
27
|
-
# @param default [Object] default value to be returned when failing to fetch a value
|
|
28
23
|
# @param block [Proc] block to be ran over the fetched value before returning it
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
24
|
+
#
|
|
25
|
+
# @overload initialize(options_hash={}, &block)
|
|
26
|
+
# @param options [Hash] options of initialization
|
|
27
|
+
# @option options keys [Array] keys of keys to be crawled
|
|
28
|
+
# @option options case [Symbol] case type of the keys
|
|
29
|
+
# - snake: snake_cased keys
|
|
30
|
+
# - lower_camel: lowerCamelCased keys
|
|
31
|
+
# - upper_camel: UperCamelCased keys
|
|
32
|
+
# @option options compact [Boolean] flag signallying if nil values should be removed of array
|
|
33
|
+
# @option options default [Object] default value to be returned when failing to fetch a value
|
|
34
|
+
#
|
|
35
|
+
# @overload initialize(options, &block)
|
|
36
|
+
# @param options [Arstotzka::Options] options of initialization object
|
|
37
|
+
def initialize(options = {}, &block)
|
|
38
|
+
self.options = options
|
|
39
|
+
|
|
34
40
|
@post_process = block || proc { |value| value }
|
|
35
41
|
end
|
|
36
42
|
|
|
37
|
-
# Crawls into the hash looking for all keys in the given
|
|
38
|
-
#
|
|
43
|
+
# Crawls into the hash looking for all keys in the given keys
|
|
44
|
+
#
|
|
39
45
|
# @return [Object] value fetched from the last Hash#fetch call using the last part
|
|
40
|
-
# of
|
|
46
|
+
# of keys
|
|
41
47
|
#
|
|
42
48
|
# @example
|
|
43
|
-
# crawler = Arstotzka::Crawler.new(%w(person information first_name))
|
|
49
|
+
# crawler = Arstotzka::Crawler.new(keys: %w(person information first_name))
|
|
44
50
|
# hash = {
|
|
45
51
|
# person: {
|
|
46
52
|
# 'information' => {
|
|
@@ -52,8 +58,8 @@ module Arstotzka
|
|
|
52
58
|
#
|
|
53
59
|
# @example
|
|
54
60
|
# crawler = Arstotzka::Crawler.new(
|
|
55
|
-
# %w(companies games hero),
|
|
56
|
-
# compact: true,
|
|
61
|
+
# keys: %w(companies games hero),
|
|
62
|
+
# compact: true, case: :snake
|
|
57
63
|
# )
|
|
58
64
|
# games_hash = {
|
|
59
65
|
# 'companies' => [{
|
|
@@ -73,16 +79,16 @@ module Arstotzka
|
|
|
73
79
|
#
|
|
74
80
|
# @example
|
|
75
81
|
# crawler = Arstotzka::Crawler.new(
|
|
76
|
-
# %w(companies games hero),
|
|
77
|
-
# compact: true,
|
|
82
|
+
# keys: %w(companies games hero),
|
|
83
|
+
# compact: true, case: :snake, default: 'NO HERO'
|
|
78
84
|
# )
|
|
79
85
|
#
|
|
80
86
|
# crawler.value(games_hash) # returns [['NO HERO', 'Rakhar'], 'NO HERO']
|
|
81
87
|
#
|
|
82
88
|
# @example
|
|
83
89
|
# crawler = Arstotzka::Crawler.new(
|
|
84
|
-
# %w(companies games hero),
|
|
85
|
-
# compact: true,
|
|
90
|
+
# keys: %w(companies games hero),
|
|
91
|
+
# compact: true, case: :snake
|
|
86
92
|
# ) { |value| value.&to_sym }
|
|
87
93
|
#
|
|
88
94
|
# crawler.value(games_hash) # returns [[:Rakhar]]
|
|
@@ -95,7 +101,8 @@ module Arstotzka
|
|
|
95
101
|
private
|
|
96
102
|
|
|
97
103
|
# @private
|
|
98
|
-
attr_reader :post_process, :
|
|
104
|
+
attr_reader :post_process, :options
|
|
105
|
+
delegate :keys, :compact, :default, to: :options
|
|
99
106
|
|
|
100
107
|
# Fetch the value from hash by crawling the keys
|
|
101
108
|
#
|
|
@@ -134,10 +141,7 @@ module Arstotzka
|
|
|
134
141
|
#
|
|
135
142
|
# @return [Arstotzka::Reader] Object responsible for extracting values out of the hash
|
|
136
143
|
def reader
|
|
137
|
-
@reader ||= Arstotzka::Reader.new(
|
|
138
|
-
path: path,
|
|
139
|
-
case_type: case_type
|
|
140
|
-
)
|
|
144
|
+
@reader ||= Arstotzka::Reader.new(options)
|
|
141
145
|
end
|
|
142
146
|
|
|
143
147
|
# @private
|