json_parser 1.2.0 → 1.3.0

Sign up to get free protection for your applications and to get access to all the features.
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