json_parser 1.2.0 → 1.3.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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: ac23553db9c63acec489ac62b9195861e901dc7b
4
- data.tar.gz: a494a82d7968db4b2586a37d3680c73de98cdab6
3
+ metadata.gz: 23023390388f2c93f237ca15e4ac5305ff793322
4
+ data.tar.gz: '099a4157fc3fd9841d747de641bd3f4a5534f1e6'
5
5
  SHA512:
6
- metadata.gz: b1ba7ad9cad67a33477b769b6cd5621838a43c51fa16a7b507553db62b858d204f7e17630e7ad6ff7c80403024ca891c34c5807b58fa2ce592d872cca549de50
7
- data.tar.gz: fad6348f9efe83a8752ab395ce8eb6c6b7475106de46cedaf7a4d881080dd8217da57f551c0167df0af118e2ec43d124aa8c1d39ca8a426090bbc5c029ebbb2b
6
+ metadata.gz: dd160fd952cd8670ed5bbc50f59e6dadd80e8da0acafc0c18c1ef84ffd1bea3c067329712ad273752928d0985fb4779a7c2256794b6cabc6ea903a138e62ae0a
7
+ data.tar.gz: b95c9fbe45504f95d2e5e9c8298b105ee2cc572da965b2c1f9c8ef93852e65da2ba49c7ef9c6bf31ec1f7e81df8ab0c18d162cc1ccafcef7ecae57041b413368
data/README.md CHANGED
@@ -16,31 +16,61 @@ Getting started
16
16
  ---------------
17
17
  1. Add JsonParser to your `Gemfile` and `bundle install`:
18
18
 
19
- ```ruby
20
- gem 'json_parser'
21
- ```
19
+ ```ruby
20
+ gem 'json_parser'
21
+ ```
22
22
 
23
23
  2. Include in a class that you want to wrap a json/hash
24
24
  ```ruby
25
- class Parser
25
+ class MyParser
26
26
  include JsonParser
27
+ ```
28
+
29
+ 3. Declare the keys you want to crawl
30
+ ```ruby
31
+ class MyParser
32
+ include JsonParser
27
33
 
28
- attr_reader :json
34
+ json_parse :id
35
+ json_parse :name, :age, path: :person
29
36
 
30
- def initialize(json)
31
- @json = json
32
- end
37
+ attr_reader :json
38
+
39
+ def initialize(json = {})
40
+ @json = json
33
41
  end
42
+ end
43
+
34
44
  ```
35
45
 
36
- 3. Declare the keys you want to crawl
46
+ and let it fetch values from your hash
47
+
48
+
37
49
  ```ruby
38
- class Parser
39
- json_parse :id, :dog_name, cached: true
40
- json_parse :age, type: :integer
41
- end
50
+ object = MyParser.new(
51
+ id: 10,
52
+ age: 22
53
+ person: {
54
+ name: 'Robert',
55
+ age: 22
56
+ }
57
+ )
58
+
59
+ object.name
60
+ #returns 'Robert'
61
+ ```
62
+
63
+ this is usefull when trying to fetch data from hashes missing nodes
64
+
65
+ ```ruby
66
+ MyParser.new.name
67
+ #returns nil
42
68
  ```
43
69
 
70
+ 4. fully customise the way you crawl / fetch the information with [Options](#options)
71
+
72
+ 5. Create custom [typecast](#TypeCast)
73
+
44
74
  Options
45
75
  -------
46
76
  - path: path where to find the sub hash that contains the key (empty by default)
@@ -52,4 +82,100 @@ Options
52
82
  - flatten: indicator telling that to flattern the resulting array (false by default)
53
83
  - after: name of a method to be called after with the resulting value
54
84
  - case: case of the keys from the json (camel by default)
55
- - type: Type that the value must be cast into
85
+ - type: Type that the value must be cast into ([TypeCast](#typecast))
86
+ - default: Default value (prior to casting and wrapping, see [Default](#default))
87
+
88
+ TypeCast
89
+ --------
90
+ The type casting, when the option `type` is passed, is done through the `JsonParser::TypeCast` which can
91
+ be extended
92
+
93
+ ```ruby
94
+ module JsonParser::TypeCast
95
+ def to_money_float(value)
96
+ value.gsub(/\$ */, '').to_f
97
+ end
98
+ end
99
+ ```
100
+
101
+ ```ruby
102
+ class MyParser
103
+ include JsonParser
104
+
105
+ json_parse :total_money, full_path: 'accounts.balance', after: :sum,
106
+ cached: true, type: :money_float
107
+ json_parse :total_owed, full_path: 'loans.value', after: :sum,
108
+ cached: true, type: :money_float
109
+
110
+ attr_reader :json
111
+
112
+ def initialize(json = {})
113
+ @json = json
114
+ end
115
+
116
+ private
117
+
118
+ #this method will receive the array of values resulting from the initial mapping
119
+ def sum(balances)
120
+ balances.sum if balances
121
+ end
122
+ end
123
+ ```
124
+
125
+ ```ruby
126
+ object = MyParser.new(
127
+ accounts: [
128
+ { balance: '$ 1000.50', type: 'checking' },
129
+ { balance: '$ 150.10', type: 'savings' },
130
+ { balance: '$ -100.24', type: 'checking' }
131
+ ],
132
+ loans: [
133
+ { value: '$ 300.50', bank: 'the_bank' },
134
+ { value: '$ 150.10', type: 'the_other_bank' },
135
+ { value: '$ 100.24', type: 'the_same_bank' }
136
+ ]
137
+ )
138
+
139
+ object.balance
140
+ #returns 1050.36
141
+ ```
142
+
143
+ Default
144
+ -------
145
+ Default value returned before typecasting or class wrapping
146
+
147
+ ```ruby
148
+ class Star
149
+ attr_reader :name
150
+
151
+ def initialize(name:)
152
+ @name = name
153
+ end
154
+ end
155
+
156
+ class StarGazer
157
+ include JsonParser
158
+
159
+ json_parse :favorite_star, full_path: 'universe.star',
160
+ default: { name: 'Sun' }, class: ::Star
161
+
162
+ attr_reader :json
163
+
164
+ def initialize(json = {})
165
+ @json = json
166
+ end
167
+ end
168
+
169
+ ```
170
+
171
+
172
+ ```ruby
173
+ star_gazer = StarGazer.new
174
+
175
+ star_gazer.favorite_star.name
176
+ #returns "Sun"
177
+
178
+ star_gazer.favorite_star.class
179
+ #returns Star
180
+ ```
181
+
@@ -4,16 +4,17 @@ class JsonParser::Builder < Sinclair
4
4
 
5
5
  def initialize(attr_names, clazz, options)
6
6
  super(clazz, {
7
- path: nil,
8
- json: :json,
7
+ after: false,
8
+ cached: false,
9
+ case: :lower_camel,
10
+ class: nil,
11
+ compact: false,
12
+ default: nil,
13
+ flatten: false,
9
14
  full_path: nil,
10
- cached: false,
11
- class: nil,
12
- compact: false,
13
- flatten: false,
14
- after: false,
15
- case: :lower_camel,
16
- type: :none
15
+ json: :json,
16
+ path: nil,
17
+ type: :none
17
18
  }.merge(options.symbolize_keys))
18
19
 
19
20
  @attr_names = attr_names
@@ -48,7 +49,7 @@ class JsonParser::Builder < Sinclair
48
49
  end
49
50
 
50
51
  def fetcher_options
51
- options.slice(:compact, :after, :type, :flatten).merge({
52
+ options.slice(:compact, :after, :type, :flatten, :default).merge({
52
53
  clazz: wrapper_clazz,
53
54
  case_type: case_type
54
55
  })
@@ -1,22 +1,21 @@
1
1
  class JsonParser::Crawler
2
- include Sinclair::OptionsParser
2
+ attr_reader :post_process, :path, :case_type, :compact, :default
3
3
 
4
- attr_reader :post_process, :path
5
-
6
- delegate :case_type, :compact, to: :options_object
7
-
8
- def initialize(path, options = {}, &block)
9
- @options = options
4
+ def initialize(path, case_type: :lower_camel, compact: false, default: nil, &block)
5
+ @case_type = case_type
6
+ @compact = compact
7
+ @default = default
10
8
  @path = path.map { |p| change_case(p) }
11
9
  @post_process = block
12
10
  end
13
11
 
14
12
  def crawl(json, index = 0)
15
- return nil if json.nil?
16
13
  return wrap(json) if is_ended?(index)
17
14
  return crawl_array(json, index) if json.is_a? Array
18
15
 
19
16
  crawl(fetch(json, index), index + 1)
17
+ rescue NoMethodError
18
+ wrap(default)
20
19
  end
21
20
 
22
21
  private
@@ -34,7 +34,7 @@ class JsonParser::Fetcher
34
34
  end
35
35
 
36
36
  def crawler_options
37
- options.slice(:case_type, :compact)
37
+ options.slice(:case_type, :compact, :default)
38
38
  end
39
39
 
40
40
  def wrapper
@@ -1,3 +1,3 @@
1
1
  module JsonParser
2
- VERSION = '1.2.0'
2
+ VERSION = '1.3.0'
3
3
  end
@@ -1,30 +1,36 @@
1
1
  class JsonParser::Wrapper
2
- include Sinclair::OptionsParser
3
2
  include JsonParser::TypeCast
4
3
 
5
- delegate :clazz, :type, to: :options_object
4
+ attr_reader :clazz, :type
6
5
 
7
- def initialize(options = {})
8
- @options = options
6
+ def initialize(clazz: nil, type: nil)
7
+ @clazz = clazz
8
+ @type = type
9
9
  end
10
10
 
11
11
  def wrap(value)
12
- return value.map { |v| wrap v } if value.is_a?(Array)
12
+ return wrap_array(value) if value.is_a?(Array)
13
+ wrap_element(value)
14
+ end
15
+
16
+ private
13
17
 
18
+ def wrap_element(value)
14
19
  value = cast(value) if has_type? && !value.nil?
15
20
  return if value.nil?
16
21
 
17
- value = clazz.new(value) if clazz
18
- value
22
+ clazz ? clazz.new(value) : value
19
23
  end
20
24
 
21
- private
25
+ def wrap_array(array)
26
+ array.map { |v| wrap v }
27
+ end
22
28
 
23
29
  def has_type?
24
30
  type.present? && type != :none
25
31
  end
26
32
 
27
33
  def cast(value)
28
- send("to_#{type}", value)
34
+ public_send("to_#{type}", value)
29
35
  end
30
36
  end
@@ -0,0 +1,27 @@
1
+ {
2
+ "banks": [
3
+ {
4
+ "name": "bank_1",
5
+ "accounts": [
6
+ {
7
+ "type": "savings",
8
+ "balance": 1000.00
9
+ }, {
10
+ "type": "checking",
11
+ "balance": 1500.00
12
+ }
13
+ ]
14
+ }, {
15
+ "name": "bank_2",
16
+ "accounts": [
17
+ {
18
+ "type": "savings",
19
+ "balance": 50.00
20
+ }, {
21
+ "type": "checking",
22
+ "balance": -500.00
23
+ }
24
+ ]
25
+ }
26
+ ]
27
+ }
@@ -0,0 +1,20 @@
1
+ {
2
+ "banks": [
3
+ {
4
+ "name": "bank_1",
5
+ "accounts": [
6
+ {
7
+ "type": "savings",
8
+ "balance": 1000.00
9
+ }, {
10
+ "type": "checking"
11
+ }
12
+ ]
13
+ }, {
14
+ "name": "bank_2",
15
+ "accounts": null
16
+ }, {
17
+ "name": "bank_3"
18
+ }
19
+ ]
20
+ }
@@ -35,5 +35,4 @@
35
35
  {"race": {"species": {"name": "Macaque monkey"}}},
36
36
  {"race": {"species": {"name": "Mexican redknee tarantula"}}}
37
37
  ]
38
-
39
38
  }
@@ -0,0 +1,5 @@
1
+ {
2
+ "user": {
3
+ "name": null
4
+ }
5
+ }
@@ -0,0 +1,37 @@
1
+ require 'spec_helper'
2
+
3
+ describe 'default option' do
4
+ subject do
5
+ StarGazer.new(hash).favorite_star
6
+ end
7
+
8
+ let(:hash) { {} }
9
+
10
+ context 'when node is not found' do
11
+ it 'returns the default before wrapping' do
12
+ expect(subject.name).to eq('Sun')
13
+ end
14
+
15
+ it 'wraps the returned value in a class' do
16
+ expect(subject).to be_a(Star)
17
+ end
18
+ end
19
+
20
+ context 'when node is not missing' do
21
+ let(:hash) do
22
+ {
23
+ universe: {
24
+ star: { name: 'Antares' }
25
+ }
26
+ }
27
+ end
28
+
29
+ it 'returns the value before wrapping' do
30
+ expect(subject.name).to eq('Antares')
31
+ end
32
+
33
+ it 'wraps the returned value in a class' do
34
+ expect(subject).to be_a(Star)
35
+ end
36
+ end
37
+ end
@@ -0,0 +1,86 @@
1
+ require 'spec_helper'
2
+
3
+ describe MyParser do
4
+ subject { described_class.new(hash) }
5
+
6
+ let(:hash) do
7
+ {
8
+ id: 10,
9
+ person: {
10
+ name: 'Robert',
11
+ age: 22
12
+ },
13
+ accounts: [
14
+ { balance: '$ 1000.50', type: 'checking' },
15
+ { balance: '$ 150.10', type: 'savings' },
16
+ { balance: '$ -100.24', type: 'checking' }
17
+ ],
18
+ loans: [
19
+ { value: '$ 300.50', bank: 'the_bank' },
20
+ { value: '$ 150.10', type: 'the_other_bank' },
21
+ { value: '$ 100.24', type: 'the_same_bank' }
22
+ ]
23
+ }
24
+ end
25
+
26
+ describe 'id' do
27
+ it 'returns the parsed id' do
28
+ expect(subject.id).to eq(10)
29
+ end
30
+ end
31
+
32
+ describe 'name' do
33
+ it 'returns the parsed name' do
34
+ expect(subject.name).to eq('Robert')
35
+ end
36
+
37
+ context 'when person is missing' do
38
+ subject { described_class.new }
39
+
40
+ it do
41
+ expect { subject.name }.not_to raise_error
42
+ end
43
+
44
+ it do
45
+ expect(subject.name).to be_nil
46
+ end
47
+ end
48
+ end
49
+
50
+ describe 'age' do
51
+ it do
52
+ expect(subject.age).to be_a(Integer)
53
+ end
54
+
55
+ it 'returns the parsed age' do
56
+ expect(subject.age).to eq(22)
57
+ end
58
+ end
59
+
60
+ describe '#total_money' do
61
+ it do
62
+ expect(subject.total_money).to be_a(Float)
63
+ end
64
+
65
+ it 'summs all the balance in the accounts' do
66
+ expect(subject.total_money).to eq(1050.36)
67
+ end
68
+
69
+ context 'when there is a node missing' do
70
+ let(:hash) { {} }
71
+ it 'returns nil' do
72
+ expect(subject.total_money).to be_nil
73
+ end
74
+ end
75
+ end
76
+
77
+ describe '#total_owed' do
78
+ it do
79
+ expect(subject.total_owed).to be_a(Float)
80
+ end
81
+
82
+ it 'summs all the balance in the accounts' do
83
+ expect(subject.total_owed).to eq(550.84)
84
+ end
85
+ end
86
+ end
@@ -92,11 +92,11 @@ describe JsonParser::Builder do
92
92
 
93
93
  context 'when wrapping with a class' do
94
94
  let(:json) { { person: name } }
95
- let(:options) { { class: JsonParser::Person } }
95
+ let(:options) { { class: Person } }
96
96
  let(:attr_name) { :person }
97
97
 
98
98
  it do
99
- expect(instance.person).to be_a(JsonParser::Person)
99
+ expect(instance.person).to be_a(Person)
100
100
  end
101
101
 
102
102
  it 'fills the new instance with the information fetched' do
@@ -104,7 +104,7 @@ describe JsonParser::Builder do
104
104
  end
105
105
 
106
106
  context 'when option key is a string' do
107
- let(:options) { { 'class' => JsonParser::Person } }
107
+ let(:options) { { 'class' => Person } }
108
108
 
109
109
  it 'fills the new instance with the information fetched' do
110
110
  expect(instance.person.name).to eq(name)
@@ -8,7 +8,8 @@ describe JsonParser::Crawler do
8
8
  let(:path) { '' }
9
9
  let(:default_options) { { case_type: :lower_camel} }
10
10
  let(:options) { {} }
11
- let(:json) { load_json_fixture_file('json_parser.json') }
11
+ let(:json_file) { 'json_parser.json' }
12
+ let(:json) { load_json_fixture_file(json_file) }
12
13
  let(:value) { subject.crawl(json) }
13
14
 
14
15
  context 'when parsing with a path' do
@@ -17,6 +18,14 @@ describe JsonParser::Crawler do
17
18
  it 'retrieves attribute from base json' do
18
19
  expect(value).to eq(json['user']['name'])
19
20
  end
21
+
22
+ context 'when calling twice' do
23
+ before { subject.crawl(json) }
24
+
25
+ it 'can still crawl' do
26
+ expect(value).to eq(json['user']['name'])
27
+ end
28
+ end
20
29
  end
21
30
 
22
31
  context 'crawler finds a nil attribute' do
@@ -31,6 +40,38 @@ describe JsonParser::Crawler do
31
40
  end
32
41
  end
33
42
 
43
+ context 'when there is an array of arrays' do
44
+ let(:json_file) { 'accounts.json' }
45
+ let(:path) { %w(banks accounts balance) }
46
+
47
+ it 'returns the values as array of arrays' do
48
+ expect(value).to eq([[1000.0, 1500.0], [50.0, -500.0]])
49
+ end
50
+
51
+ context 'when there is a missing node' do
52
+ let(:json_file) { 'accounts_missing.json' }
53
+
54
+ it 'returns the missing values as nil' do
55
+ expect(value).to eq([[1000.0, nil], nil, nil])
56
+ end
57
+
58
+ context 'when setting a default' do
59
+ let(:options) { { default: 10 } }
60
+
61
+ it 'returns the missing values as default' do
62
+ expect(value).to eq([[1000.0, nil], 10, 10])
63
+ end
64
+ end
65
+
66
+ context 'when setting compact' do
67
+ let(:options) { { compact: true } }
68
+ it 'returns the missing values as nil' do
69
+ expect(value).to eq([[1000.0]])
70
+ end
71
+ end
72
+ end
73
+ end
74
+
34
75
  context 'when json is empty' do
35
76
  let(:json) { nil }
36
77
  let(:path) { %w(car model) }
@@ -97,6 +138,59 @@ describe JsonParser::Crawler do
97
138
  end
98
139
  end
99
140
 
141
+ context 'with default option' do
142
+ let(:default_value) { 'NotFound' }
143
+ let(:options) { { default: default_value } }
144
+ let(:path) { %w(projects name) }
145
+
146
+ context 'when there is a key missing' do
147
+ it 'returns the default value' do
148
+ expect(value).to eq(default_value)
149
+ end
150
+
151
+ context 'when wrapping it with a class' do
152
+ let(:block) { proc { |v| Person.new(v) } }
153
+
154
+ it 'wrap it with the class' do
155
+ expect(value).to be_a(Person)
156
+ end
157
+
158
+ it 'wraps the default value' do
159
+ expect(value.name).to eq(default_value)
160
+ end
161
+ end
162
+ end
163
+
164
+ context 'when the key is not missing but the value is nil' do
165
+ let(:json_file) { 'person.json' }
166
+ let(:path) { %w(user name) }
167
+
168
+ it { expect(value).to be_nil }
169
+
170
+ context 'when wrapping it with a class' do
171
+ let(:block) { proc { |v| Person.new(v) } }
172
+
173
+ it 'wrap it with the class' do
174
+ expect(value).to be_a(Person)
175
+ end
176
+
177
+ it 'wraps the default value' do
178
+ expect(value.name).to be_nil
179
+ end
180
+ end
181
+ end
182
+
183
+ context 'when the node is missing but default has the same node' do
184
+ let(:default_value) { { node: { value: 1 } } }
185
+ let(:path) { %w(node node node) }
186
+ let(:json) { {} }
187
+
188
+ it 'does not crawl through default value' do
189
+ expect(value).to eq(default_value)
190
+ end
191
+ end
192
+ end
193
+
100
194
  context 'when using a snake case' do
101
195
  let(:json) { { snake_cased: 'snake', snakeCased: 'Camel' }.stringify_keys }
102
196
  let(:path) { [ 'snake_cased' ] }
@@ -1,14 +1,10 @@
1
1
  require 'spec_helper'
2
2
 
3
3
  describe JsonParser::Fetcher do
4
- class JsonParser::Fetcher::Dummy
5
- end
6
-
7
4
  let(:subject) do
8
- described_class.new json, path, instance, default_options.merge(options)
5
+ described_class.new json, path, instance, options
9
6
  end
10
7
  let(:path) { '' }
11
- let(:default_options) { { case_type: :snake} }
12
8
  let(:instance) { JsonParser::Fetcher::Dummy.new }
13
9
  let(:json) { load_json_fixture_file('json_parser.json') }
14
10
  let(:value) { subject.fetch }
@@ -71,4 +67,30 @@ describe JsonParser::Fetcher do
71
67
  end
72
68
  end
73
69
  end
70
+
71
+ describe 'after option' do
72
+ let(:instance) { MyParser.new(json) }
73
+ let(:json) { [ 100, 250, -25] }
74
+ let(:options) { { after: :sum } }
75
+
76
+ it 'applies after call ' do
77
+ expect(subject.fetch).to eq(325)
78
+ end
79
+ end
80
+
81
+ describe 'clazz options' do
82
+ let(:path) { 'name' }
83
+ let(:name) { 'Robert' }
84
+ let(:json) { { name: name } }
85
+ let(:options) { { clazz: wrapper } }
86
+ let(:wrapper) { Person }
87
+
88
+ it 'wraps the result in an object' do
89
+ expect(subject.fetch).to be_a(wrapper)
90
+ end
91
+
92
+ it 'sets the wrapper with the fetched value' do
93
+ expect(subject.fetch.name).to eq(name)
94
+ end
95
+ end
74
96
  end
@@ -1,14 +1,6 @@
1
1
  require 'spec_helper'
2
2
 
3
3
  describe JsonParser::Wrapper do
4
-
5
- class JsonParser::Wrapper::DummyWrapper
6
- attr_reader :value
7
- def initialize(value)
8
- @value = value
9
- end
10
- end
11
-
12
4
  let(:options) { {} }
13
5
  let(:subject) { described_class.new options }
14
6
  let(:hash) { { a: 1 } }
@@ -76,7 +68,7 @@ describe JsonParser::Wrapper do
76
68
  end
77
69
 
78
70
  context 'when passing clazz parameter' do
79
- let(:options) { { type: type, clazz: JsonParser::Wrapper::DummyWrapper } }
71
+ let(:options) { { type: type, clazz: JsonParser::Wrapper::Dummy } }
80
72
 
81
73
  it do
82
74
  expect(result).to be_nil
@@ -94,25 +86,25 @@ describe JsonParser::Wrapper do
94
86
  }
95
87
 
96
88
  context 'when passing clazz parameter' do
97
- let(:options) { { type: type, clazz: JsonParser::Wrapper::DummyWrapper } }
89
+ let(:options) { { type: type, clazz: JsonParser::Wrapper::Dummy } }
98
90
 
99
91
  it_behaves_like 'a result that is type cast', {
100
92
  integer: NilClass,
101
93
  float: NilClass,
102
- string: JsonParser::Wrapper::DummyWrapper
94
+ string: JsonParser::Wrapper::Dummy
103
95
  }
104
96
  end
105
97
  end
106
98
 
107
99
  context 'when passing clazz parameter' do
108
100
  let(:value) { 1 }
109
- let(:options) { { type: type, clazz: JsonParser::Wrapper::DummyWrapper } }
101
+ let(:options) { { type: type, clazz: JsonParser::Wrapper::Dummy } }
110
102
  let(:cast) { result.value }
111
103
 
112
104
  it_behaves_like 'casts basic types'
113
105
 
114
106
  it 'wraps the result inside the given class' do
115
- expect(result).to be_a(JsonParser::Wrapper::DummyWrapper)
107
+ expect(result).to be_a(JsonParser::Wrapper::Dummy)
116
108
  end
117
109
  end
118
110
 
@@ -46,7 +46,7 @@ describe JsonParser do
46
46
  let(:attribute) { :house }
47
47
 
48
48
  it 'returns an onject wrap' do
49
- expect(value).to be_a(JsonParser::House)
49
+ expect(value).to be_a(House)
50
50
  end
51
51
 
52
52
  it 'creates the object with the given json' do
@@ -61,7 +61,7 @@ describe JsonParser do
61
61
  it 'returns an array of json wrapped' do
62
62
  expect(value).to be_a(Array)
63
63
  value.each do |object|
64
- expect(object).to be_a(JsonParser::Game)
64
+ expect(object).to be_a(Game)
65
65
  end
66
66
  end
67
67
 
@@ -76,7 +76,7 @@ describe JsonParser do
76
76
  value.each do |object|
77
77
  expect(object).to be_a(Array)
78
78
  object.each do |game|
79
- expect(game).to be_a(JsonParser::Game)
79
+ expect(game).to be_a(Game)
80
80
  end
81
81
  end
82
82
  end
@@ -93,7 +93,7 @@ describe JsonParser do
93
93
  end
94
94
 
95
95
  it 'returns an onject wrap' do
96
- expect(value).to be_a(JsonParser::House)
96
+ expect(value).to be_a(House)
97
97
  end
98
98
 
99
99
  it 'creates the object with the given json' do
@@ -1,16 +1,12 @@
1
1
  require 'simplecov'
2
- SimpleCov.start
2
+ SimpleCov.start do
3
+ add_filter 'spec/support/models/'
4
+ end
3
5
 
4
6
  require 'pry-nav'
5
7
  require 'json_parser'
6
8
  require 'safe_attribute_assignment'
7
9
 
8
- module JsonParser
9
- models = File.expand_path("spec/support/models/*.rb")
10
- Dir[models].each do |file|
11
- autoload file.gsub(/.*\/(.*)\..*/, '\1').camelize.to_sym, file
12
- end
13
- end
14
10
  support_files = File.expand_path("spec/support/**/*.rb")
15
11
  Dir[support_files].each { |file| require file }
16
12
 
@@ -0,0 +1,5 @@
1
+ models = File.expand_path("spec/support/models/*.rb")
2
+ Dir[models].sort.each do |file|
3
+ autoload file.gsub(/.*\/(.*)\..*/, '\1').camelize.to_sym, file
4
+ end
5
+
@@ -1,4 +1,4 @@
1
- class JsonParser::Game
1
+ class Game
2
2
  include JsonParser
3
3
  include SafeAttributeAssignment
4
4
  attr_reader :json
@@ -1,4 +1,4 @@
1
- class JsonParser::House
1
+ class House
2
2
  include JsonParser
3
3
  include ::SafeAttributeAssignment
4
4
  attr_reader :json
@@ -6,10 +6,10 @@ class JsonParser::Dummy
6
6
  json_parse :name, path: 'user'
7
7
  json_parse :father_name, full_path: 'father.name'
8
8
  json_parse :age, cached: true
9
- json_parse :house, class: JsonParser::House
10
- json_parse :old_house, class: JsonParser::House, cached: true
11
- json_parse :games, class: JsonParser::Game
12
- json_parse :games_filtered, class: JsonParser::Game, after: :filter_games, full_path: 'games'
9
+ json_parse :house, class: ::House
10
+ json_parse :old_house, class: ::House, cached: true
11
+ json_parse :games, class: ::Game
12
+ json_parse :games_filtered, class: ::Game, after: :filter_games, full_path: 'games'
13
13
 
14
14
  def initialize(json)
15
15
  @json = json
@@ -0,0 +1,3 @@
1
+ class JsonParser::Fetcher::Dummy
2
+ end
3
+
@@ -0,0 +1,6 @@
1
+ module JsonParser::TypeCast
2
+ def to_money_float(value)
3
+ value.gsub(/\$ */, '').to_f
4
+ end
5
+ end
6
+
@@ -0,0 +1,7 @@
1
+ class JsonParser::Wrapper::Dummy
2
+ attr_reader :value
3
+ def initialize(value)
4
+ @value = value
5
+ end
6
+ end
7
+
@@ -0,0 +1,28 @@
1
+ class MyParser
2
+ include JsonParser
3
+
4
+ json_parse :id
5
+ json_parse :name, :age, path: :person
6
+ json_parse :total_money, full_path: 'accounts.balance', after: :sum,
7
+ cached: true, type: :money_float
8
+ json_parse :total_owed, full_path: 'loans.value', after: :sum,
9
+ cached: true, type: :money_float
10
+
11
+ attr_reader :json
12
+
13
+ def initialize(json = {})
14
+ @json = json
15
+ end
16
+
17
+ private
18
+
19
+ def sum(balances)
20
+ balances.sum if balances
21
+ end
22
+
23
+ models = File.expand_path("spec/support/models/my_parser/*.rb")
24
+ Dir[models].each do |file|
25
+ autoload file.gsub(/.*\/(.*)\..*/, '\1').camelize.to_sym, file
26
+ end
27
+ end
28
+
@@ -1,4 +1,4 @@
1
- class JsonParser::Person
1
+ class Person
2
2
  attr_reader :name
3
3
 
4
4
  def initialize(name)
@@ -0,0 +1,7 @@
1
+ class Star
2
+ attr_reader :name
3
+
4
+ def initialize(name:)
5
+ @name = name
6
+ end
7
+ end
@@ -0,0 +1,13 @@
1
+ class StarGazer
2
+ include JsonParser
3
+
4
+ json_parse :favorite_star, full_path: 'universe.star',
5
+ default: { name: 'Sun' }, class: ::Star
6
+
7
+ attr_reader :json
8
+
9
+ def initialize(json = {})
10
+ @json = json
11
+ end
12
+ end
13
+
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: json_parser
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.2.0
4
+ version: 1.3.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Bidu Dev's Team
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2018-05-24 00:00:00.000000000 Z
11
+ date: 2018-05-31 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: activesupport
@@ -147,7 +147,12 @@ files:
147
147
  - lib/json_parser/type_cast.rb
148
148
  - lib/json_parser/version.rb
149
149
  - lib/json_parser/wrapper.rb
150
+ - spec/fixtures/accounts.json
151
+ - spec/fixtures/accounts_missing.json
150
152
  - spec/fixtures/json_parser.json
153
+ - spec/fixtures/person.json
154
+ - spec/integration/readme/default_spec.rb
155
+ - spec/integration/readme/my_parser_spec.rb
151
156
  - spec/lib/json_parser/builder_spec.rb
152
157
  - spec/lib/json_parser/crawler_spec.rb
153
158
  - spec/lib/json_parser/fetcher_spec.rb
@@ -155,10 +160,17 @@ files:
155
160
  - spec/lib/json_parser_spec.rb
156
161
  - spec/spec_helper.rb
157
162
  - spec/support/fixture_helpers.rb
158
- - spec/support/models/dummy.rb
163
+ - spec/support/models.rb
159
164
  - spec/support/models/game.rb
160
165
  - spec/support/models/house.rb
166
+ - spec/support/models/json_parser/dummy.rb
167
+ - spec/support/models/json_parser/fetcher/dummy.rb
168
+ - spec/support/models/json_parser/type_cast.rb
169
+ - spec/support/models/json_parser/wrapper/dummy.rb
170
+ - spec/support/models/my_parser.rb
161
171
  - spec/support/models/person.rb
172
+ - spec/support/models/star.rb
173
+ - spec/support/models/star_gazer.rb
162
174
  - spec/support/shared_examples/wrapper.rb
163
175
  homepage: https://github.com/Bidu/json_parser
164
176
  licenses: []
@@ -184,7 +196,12 @@ signing_key:
184
196
  specification_version: 4
185
197
  summary: Json Parser
186
198
  test_files:
199
+ - spec/fixtures/accounts.json
200
+ - spec/fixtures/accounts_missing.json
187
201
  - spec/fixtures/json_parser.json
202
+ - spec/fixtures/person.json
203
+ - spec/integration/readme/default_spec.rb
204
+ - spec/integration/readme/my_parser_spec.rb
188
205
  - spec/lib/json_parser/builder_spec.rb
189
206
  - spec/lib/json_parser/crawler_spec.rb
190
207
  - spec/lib/json_parser/fetcher_spec.rb
@@ -192,8 +209,15 @@ test_files:
192
209
  - spec/lib/json_parser_spec.rb
193
210
  - spec/spec_helper.rb
194
211
  - spec/support/fixture_helpers.rb
195
- - spec/support/models/dummy.rb
212
+ - spec/support/models.rb
196
213
  - spec/support/models/game.rb
197
214
  - spec/support/models/house.rb
215
+ - spec/support/models/json_parser/dummy.rb
216
+ - spec/support/models/json_parser/fetcher/dummy.rb
217
+ - spec/support/models/json_parser/type_cast.rb
218
+ - spec/support/models/json_parser/wrapper/dummy.rb
219
+ - spec/support/models/my_parser.rb
198
220
  - spec/support/models/person.rb
221
+ - spec/support/models/star.rb
222
+ - spec/support/models/star_gazer.rb
199
223
  - spec/support/shared_examples/wrapper.rb