arstotzka 1.0.3 → 1.0.4
Sign up to get free protection for your applications and to get access to all the features.
- 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
@@ -1,27 +1,43 @@
|
|
1
|
-
# frozen_string_literal:
|
2
|
-
|
3
|
-
require 'spec_helper'
|
1
|
+
# frozen_string_literal: truie
|
4
2
|
|
5
3
|
describe Arstotzka::Wrapper do
|
4
|
+
subject(:wrapper) { described_class.new(clazz: clazz, type: type) }
|
5
|
+
|
6
|
+
let(:type) { nil }
|
7
|
+
let(:clazz) { nil }
|
8
|
+
|
6
9
|
describe 'yard' do
|
7
10
|
describe '#wrap' do
|
8
|
-
|
9
|
-
let(:clazz) { nil }
|
10
|
-
let(:type) { nil }
|
11
|
-
|
12
|
-
context 'when definning clazz' do
|
11
|
+
context 'when clazz is defined' do
|
13
12
|
let(:clazz) { Person }
|
13
|
+
let(:value) { 'john' }
|
14
|
+
|
15
|
+
it 'wraps value with the clazz' do
|
16
|
+
expect(wrapper.wrap(value)).to eq(Person.new(value))
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
context 'when type is defined' do
|
21
|
+
let(:type) { :integer }
|
22
|
+
let(:value) { %w[10 20 30] }
|
14
23
|
|
15
|
-
it '
|
16
|
-
expect(
|
24
|
+
it 'converts value to type' do
|
25
|
+
expect(wrapper.wrap(value)).to eq([10, 20, 30])
|
17
26
|
end
|
18
27
|
end
|
19
28
|
|
20
|
-
context 'when
|
21
|
-
let(:type)
|
29
|
+
context 'when type and class is defined' do
|
30
|
+
let(:type) { :string }
|
31
|
+
let(:clazz) { Request }
|
32
|
+
let(:value) { { 'key' => 'value' } }
|
33
|
+
let(:request) { wrapper.wrap(value) }
|
34
|
+
|
35
|
+
it 'returns a wrapped object' do
|
36
|
+
expect(request).to be_a(Request)
|
37
|
+
end
|
22
38
|
|
23
|
-
it 'casts
|
24
|
-
expect(
|
39
|
+
it 'casts before wrapping' do
|
40
|
+
expect(request.payload).to eq('{"key"=>"value"}')
|
25
41
|
end
|
26
42
|
end
|
27
43
|
end
|
@@ -3,8 +3,8 @@
|
|
3
3
|
require 'spec_helper'
|
4
4
|
|
5
5
|
describe Arstotzka do
|
6
|
-
describe
|
7
|
-
subject { Collector.new(hash) }
|
6
|
+
describe 'yard' do
|
7
|
+
subject(:collector) { Collector.new(hash) }
|
8
8
|
|
9
9
|
let(:hash) { JSON.parse json }
|
10
10
|
let(:json) do
|
@@ -65,37 +65,37 @@ describe Arstotzka do
|
|
65
65
|
|
66
66
|
describe '#full_name' do
|
67
67
|
it 'returns the full_name' do
|
68
|
-
expect(
|
68
|
+
expect(collector.full_name).to eq('Kelly Khan')
|
69
69
|
end
|
70
70
|
|
71
71
|
it 'does not cache name' do
|
72
72
|
expect do
|
73
73
|
hash['person']['fullName'] = 'Robert'
|
74
|
-
end.to change(
|
74
|
+
end.to change(collector, :full_name).to('Robert')
|
75
75
|
end
|
76
76
|
end
|
77
77
|
|
78
78
|
describe '#age' do
|
79
79
|
it 'returns the age' do
|
80
|
-
expect(
|
80
|
+
expect(collector.age).to eq(32)
|
81
81
|
end
|
82
82
|
end
|
83
83
|
|
84
84
|
describe '#gender' do
|
85
85
|
it 'returns person gender' do
|
86
|
-
expect(
|
86
|
+
expect(collector.gender).to eq(Collector::FEMALE)
|
87
87
|
end
|
88
88
|
|
89
89
|
it 'does caches gender' do
|
90
90
|
expect do
|
91
91
|
hash['person']['gender'] = 'man'
|
92
|
-
end.not_to change(
|
92
|
+
end.not_to change(collector, :gender)
|
93
93
|
end
|
94
94
|
end
|
95
95
|
|
96
96
|
describe '#car_names' do
|
97
97
|
it 'returns the nick names of the cars' do
|
98
|
-
expect(
|
98
|
+
expect(collector.car_names).to eq(%w[Betty Roger Geronimo MissingName])
|
99
99
|
end
|
100
100
|
end
|
101
101
|
|
@@ -105,7 +105,7 @@ describe Arstotzka do
|
|
105
105
|
Collector::Game.new(name: 'TheNextBigThing', played: 100.0),
|
106
106
|
Collector::Game.new(name: 'Zelda', played: 90.0)
|
107
107
|
]
|
108
|
-
expect(
|
108
|
+
expect(collector.finished_games).to eq(expected)
|
109
109
|
end
|
110
110
|
end
|
111
111
|
end
|
@@ -3,6 +3,10 @@
|
|
3
3
|
require 'spec_helper'
|
4
4
|
|
5
5
|
describe Arstotzka::Builder do
|
6
|
+
subject(:builder) do
|
7
|
+
described_class.new(attr_names, clazz, **full_options)
|
8
|
+
end
|
9
|
+
|
6
10
|
let(:clazz) do
|
7
11
|
Class.new.tap do |c|
|
8
12
|
c.send(:attr_reader, :json)
|
@@ -20,19 +24,17 @@ describe Arstotzka::Builder do
|
|
20
24
|
let(:instance) { clazz.new(json) }
|
21
25
|
let(:full_options) { described_class::DEFAULT_OPTIONS.merge(options) }
|
22
26
|
|
23
|
-
subject do
|
24
|
-
described_class.new(attr_names, clazz, **full_options)
|
25
|
-
end
|
26
|
-
|
27
27
|
describe '#build' do
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
28
|
+
context 'when it is called' do
|
29
|
+
it 'adds the reader' do
|
30
|
+
expect do
|
31
|
+
builder.build
|
32
|
+
end.to add_method(attr_name).to(clazz)
|
33
|
+
end
|
32
34
|
end
|
33
35
|
|
34
|
-
context '
|
35
|
-
before {
|
36
|
+
context 'with being previously called' do
|
37
|
+
before { builder.build }
|
36
38
|
|
37
39
|
context 'when building several attributes' do
|
38
40
|
let(:attr_names) { %i[id name age] }
|
@@ -47,19 +49,19 @@ describe Arstotzka::Builder do
|
|
47
49
|
expect(instance.name).to be_nil
|
48
50
|
end
|
49
51
|
|
50
|
-
context 'when json has the property' do
|
52
|
+
context 'when json has the property as symbol key' do
|
51
53
|
let(:json) { { name: name } }
|
52
54
|
|
53
55
|
it 'fetches the value' do
|
54
56
|
expect(instance.name).to eq(name)
|
55
57
|
end
|
58
|
+
end
|
56
59
|
|
57
|
-
|
58
|
-
|
60
|
+
context 'when json has the property as string key' do
|
61
|
+
let(:json) { { 'name' => name } }
|
59
62
|
|
60
|
-
|
61
|
-
|
62
|
-
end
|
63
|
+
it 'fetches the value' do
|
64
|
+
expect(instance.name).to eq(name)
|
63
65
|
end
|
64
66
|
end
|
65
67
|
end
|
@@ -3,23 +3,25 @@
|
|
3
3
|
require 'spec_helper'
|
4
4
|
|
5
5
|
describe Arstotzka::Crawler do
|
6
|
-
subject do
|
6
|
+
subject(:crawler) do
|
7
7
|
described_class.new default_options.merge(options), &block
|
8
8
|
end
|
9
|
+
|
9
10
|
let(:block) { proc { |v| v } }
|
10
11
|
let(:path) { '' }
|
11
12
|
let(:default_options) { { path: path, case_type: :lower_camel } }
|
12
13
|
let(:options) { {} }
|
13
14
|
let(:json_file) { 'arstotzka.json' }
|
14
15
|
let(:json) { load_json_fixture_file(json_file) }
|
15
|
-
let(:value) {
|
16
|
+
let(:value) { crawler.value(json) }
|
16
17
|
|
17
18
|
context 'when no block is given' do
|
18
|
-
|
19
|
-
subject do
|
19
|
+
subject(:crawler) do
|
20
20
|
described_class.new default_options.merge(options)
|
21
21
|
end
|
22
22
|
|
23
|
+
let(:path) { %w[user name] }
|
24
|
+
|
23
25
|
it 'retrieves attribute from base json' do
|
24
26
|
expect(value).to eq(json['user']['name'])
|
25
27
|
end
|
@@ -33,7 +35,7 @@ describe Arstotzka::Crawler do
|
|
33
35
|
end
|
34
36
|
|
35
37
|
context 'when calling twice' do
|
36
|
-
before {
|
38
|
+
before { crawler.value(json) }
|
37
39
|
|
38
40
|
it 'can still crawl' do
|
39
41
|
expect(value).to eq(json['user']['name'])
|
@@ -41,7 +43,7 @@ describe Arstotzka::Crawler do
|
|
41
43
|
end
|
42
44
|
end
|
43
45
|
|
44
|
-
context 'crawler finds a nil attribute' do
|
46
|
+
context 'when crawler finds a nil attribute' do
|
45
47
|
let(:path) { %w[car model] }
|
46
48
|
|
47
49
|
it 'returns nil' do
|
@@ -78,6 +80,7 @@ describe Arstotzka::Crawler do
|
|
78
80
|
|
79
81
|
context 'when setting compact' do
|
80
82
|
let(:options) { { compact: true } }
|
83
|
+
|
81
84
|
it 'returns the missing values as nil' do
|
82
85
|
expect(value).to eq([[1000.0]])
|
83
86
|
end
|
@@ -123,13 +126,15 @@ describe Arstotzka::Crawler do
|
|
123
126
|
context 'when there are nil values' do
|
124
127
|
context 'with compact option as false' do
|
125
128
|
let(:options) { { compact: false } }
|
126
|
-
|
127
|
-
json['animals'].last['race'] = nil
|
128
|
-
end
|
129
|
+
|
129
130
|
let(:expected) do
|
130
131
|
['European squid', 'Macaque monkey', nil]
|
131
132
|
end
|
132
133
|
|
134
|
+
before do
|
135
|
+
json['animals'].last['race'] = nil
|
136
|
+
end
|
137
|
+
|
133
138
|
it 'eliminate nil values' do
|
134
139
|
expect(value).to eq(expected)
|
135
140
|
end
|
@@ -137,13 +142,15 @@ describe Arstotzka::Crawler do
|
|
137
142
|
|
138
143
|
context 'with compact option' do
|
139
144
|
let(:options) { { compact: true } }
|
140
|
-
|
141
|
-
json['animals'].last['race'] = nil
|
142
|
-
end
|
145
|
+
|
143
146
|
let(:expected) do
|
144
147
|
['European squid', 'Macaque monkey']
|
145
148
|
end
|
146
149
|
|
150
|
+
before do
|
151
|
+
json['animals'].last['race'] = nil
|
152
|
+
end
|
153
|
+
|
147
154
|
it 'eliminate nil values' do
|
148
155
|
expect(value).to eq(expected)
|
149
156
|
end
|
@@ -253,7 +260,7 @@ describe Arstotzka::Crawler do
|
|
253
260
|
expect(value).to eq(json[:id])
|
254
261
|
end
|
255
262
|
|
256
|
-
context 'crawler finds a nil attribute' do
|
263
|
+
context 'when crawler finds a nil attribute' do
|
257
264
|
let(:path) { %w[car model] }
|
258
265
|
|
259
266
|
it 'returns nil' do
|
@@ -268,6 +275,7 @@ describe Arstotzka::Crawler do
|
|
268
275
|
|
269
276
|
context 'when using key with false value' do
|
270
277
|
let(:path) { ['has_money'] }
|
278
|
+
|
271
279
|
before do
|
272
280
|
json['hasMoney'] = false
|
273
281
|
end
|
@@ -3,13 +3,14 @@
|
|
3
3
|
require 'spec_helper'
|
4
4
|
|
5
5
|
describe Arstotzka::Fetcher do
|
6
|
-
|
6
|
+
subject(:fetcher) do
|
7
7
|
described_class.new json, instance, options.merge(path: path)
|
8
8
|
end
|
9
|
+
|
9
10
|
let(:path) { '' }
|
10
11
|
let(:instance) { Arstotzka::Fetcher::Dummy.new }
|
11
12
|
let(:json) { load_json_fixture_file('arstotzka.json') }
|
12
|
-
let(:value) {
|
13
|
+
let(:value) { fetcher.fetch }
|
13
14
|
|
14
15
|
context 'when fetching with no options' do
|
15
16
|
let(:options) { {} }
|
@@ -21,7 +22,7 @@ describe Arstotzka::Fetcher do
|
|
21
22
|
|
22
23
|
context 'when calling the method twice' do
|
23
24
|
before do
|
24
|
-
|
25
|
+
fetcher.fetch
|
25
26
|
end
|
26
27
|
|
27
28
|
it 'retrieves attribute from base json' do
|
@@ -31,8 +32,9 @@ describe Arstotzka::Fetcher do
|
|
31
32
|
|
32
33
|
context 'when changing json value' do
|
33
34
|
let!(:old_value) { json['id'] }
|
35
|
+
|
34
36
|
before do
|
35
|
-
|
37
|
+
fetcher.fetch
|
36
38
|
json['id'] = 200
|
37
39
|
end
|
38
40
|
|
@@ -49,14 +51,14 @@ describe Arstotzka::Fetcher do
|
|
49
51
|
let(:options) { { flatten: true } }
|
50
52
|
|
51
53
|
it 'returns the fetched value flattened' do
|
52
|
-
expect(
|
54
|
+
expect(fetcher.fetch).to eq((1..8).to_a)
|
53
55
|
end
|
54
56
|
|
55
57
|
context 'when value is not an array' do
|
56
58
|
let(:json) { 1 }
|
57
59
|
|
58
60
|
it 'returns the fetched value flattened' do
|
59
|
-
expect(
|
61
|
+
expect(fetcher.fetch).to eq(1)
|
60
62
|
end
|
61
63
|
end
|
62
64
|
end
|
@@ -65,7 +67,7 @@ describe Arstotzka::Fetcher do
|
|
65
67
|
let(:options) { { flatten: false } }
|
66
68
|
|
67
69
|
it 'returns the fetched value non flattened' do
|
68
|
-
expect(
|
70
|
+
expect(fetcher.fetch).to eq(json)
|
69
71
|
end
|
70
72
|
end
|
71
73
|
end
|
@@ -76,7 +78,7 @@ describe Arstotzka::Fetcher do
|
|
76
78
|
let(:options) { { after: :sum } }
|
77
79
|
|
78
80
|
it 'applies after call ' do
|
79
|
-
expect(
|
81
|
+
expect(fetcher.fetch).to eq(325)
|
80
82
|
end
|
81
83
|
end
|
82
84
|
|
@@ -88,11 +90,11 @@ describe Arstotzka::Fetcher do
|
|
88
90
|
let(:wrapper) { Person }
|
89
91
|
|
90
92
|
it 'wraps the result in an object' do
|
91
|
-
expect(
|
93
|
+
expect(fetcher.fetch).to be_a(wrapper)
|
92
94
|
end
|
93
95
|
|
94
96
|
it 'sets the wrapper with the fetched value' do
|
95
|
-
expect(
|
97
|
+
expect(fetcher.fetch.name).to eq(name)
|
96
98
|
end
|
97
99
|
end
|
98
100
|
end
|
@@ -4,26 +4,26 @@ require 'spec_helper'
|
|
4
4
|
|
5
5
|
shared_examples 'reader fetchin value' do
|
6
6
|
it do
|
7
|
-
expect {
|
7
|
+
expect { reader.read(json, index) }.not_to raise_error
|
8
8
|
end
|
9
9
|
|
10
10
|
it do
|
11
|
-
expect(
|
11
|
+
expect(reader.read(json, index)).not_to be_nil
|
12
12
|
end
|
13
13
|
|
14
14
|
it 'returns the evaluated value' do
|
15
|
-
expect(
|
15
|
+
expect(reader.read(json, index)).to eq(expected)
|
16
16
|
end
|
17
17
|
|
18
|
-
context '
|
18
|
+
context 'when the json has symbolized_keys' do
|
19
19
|
it 'returns the evaluated value' do
|
20
|
-
expect(
|
20
|
+
expect(reader.read(sym_json, index)).to eq(expected)
|
21
21
|
end
|
22
22
|
end
|
23
23
|
end
|
24
24
|
|
25
25
|
describe Arstotzka::Reader do
|
26
|
-
subject do
|
26
|
+
subject(:reader) do
|
27
27
|
described_class.new(path: path, case_type: case_type)
|
28
28
|
end
|
29
29
|
|
@@ -45,14 +45,14 @@ describe Arstotzka::Reader do
|
|
45
45
|
let(:json) { full_json['user'] }
|
46
46
|
let(:index) { 1 }
|
47
47
|
|
48
|
-
context '
|
48
|
+
context 'with snake_case type' do
|
49
49
|
let(:path) { %w[user FullName] }
|
50
50
|
let(:expected) { json['full_name'] }
|
51
51
|
|
52
52
|
it_behaves_like 'reader fetchin value'
|
53
53
|
end
|
54
54
|
|
55
|
-
context '
|
55
|
+
context 'with upper_camel type' do
|
56
56
|
let(:case_type) { :upper_camel }
|
57
57
|
let(:path) { %w[user login_name] }
|
58
58
|
let(:expected) { json['LoginName'] }
|
@@ -60,7 +60,7 @@ describe Arstotzka::Reader do
|
|
60
60
|
it_behaves_like 'reader fetchin value'
|
61
61
|
end
|
62
62
|
|
63
|
-
context '
|
63
|
+
context 'with lower_camel type' do
|
64
64
|
let(:case_type) { :lower_camel }
|
65
65
|
let(:path) { %w[user birth_date] }
|
66
66
|
let(:expected) { json['birthDate'] }
|
@@ -75,12 +75,12 @@ describe Arstotzka::Reader do
|
|
75
75
|
let(:path) { %w[user password_reminder] }
|
76
76
|
|
77
77
|
it do
|
78
|
-
expect(
|
78
|
+
expect(reader.read(json, index)).to be_nil
|
79
79
|
end
|
80
80
|
|
81
|
-
context '
|
81
|
+
context 'when keys are symbol' do
|
82
82
|
it do
|
83
|
-
expect(
|
83
|
+
expect(reader.read(sym_json, index)).to be_nil
|
84
84
|
end
|
85
85
|
end
|
86
86
|
end
|
@@ -90,7 +90,7 @@ describe Arstotzka::Reader do
|
|
90
90
|
let(:json) { { key: 'symbol', 'key' => 'string' } }
|
91
91
|
|
92
92
|
it 'fetches the string key first' do
|
93
|
-
expect(
|
93
|
+
expect(reader.read(json, index)).to eq('string')
|
94
94
|
end
|
95
95
|
end
|
96
96
|
end
|
@@ -100,7 +100,7 @@ describe Arstotzka::Reader do
|
|
100
100
|
|
101
101
|
it do
|
102
102
|
expect do
|
103
|
-
|
103
|
+
reader.read(json, index)
|
104
104
|
end.to raise_error(Arstotzka::Exception::KeyNotFound)
|
105
105
|
end
|
106
106
|
end
|
@@ -110,13 +110,13 @@ describe Arstotzka::Reader do
|
|
110
110
|
context 'when index is within path' do
|
111
111
|
let(:index) { 1 }
|
112
112
|
|
113
|
-
it { expect(
|
113
|
+
it { expect(reader).not_to be_ended(index) }
|
114
114
|
end
|
115
115
|
|
116
116
|
context 'when index is outside path' do
|
117
117
|
let(:index) { 2 }
|
118
118
|
|
119
|
-
it { expect(
|
119
|
+
it { expect(reader).to be_ended(index) }
|
120
120
|
end
|
121
121
|
end
|
122
122
|
end
|
@@ -30,15 +30,21 @@ describe Arstotzka::Wrapper do
|
|
30
30
|
|
31
31
|
it 'creates new instance from given class' do
|
32
32
|
expect(result).to be_a(OpenStruct)
|
33
|
+
end
|
34
|
+
|
35
|
+
it 'uses the given value on object initialization' do
|
33
36
|
expect(result.a).to eq(hash[:a])
|
34
37
|
end
|
35
38
|
|
36
39
|
context 'with an array as value' do
|
37
40
|
let(:value) { [hash] }
|
38
41
|
|
39
|
-
it 'returns an array
|
42
|
+
it 'returns an array' do
|
40
43
|
expect(result).to be_a(Array)
|
41
|
-
|
44
|
+
end
|
45
|
+
|
46
|
+
it 'returns an array of objects of the given class' do
|
47
|
+
expect(result).to all(be_a(OpenStruct))
|
42
48
|
end
|
43
49
|
end
|
44
50
|
end
|
data/spec/lib/arstotzka_spec.rb
CHANGED
@@ -35,6 +35,7 @@ describe Arstotzka do
|
|
35
35
|
context 'when caching the value' do
|
36
36
|
let(:attribute) { :age }
|
37
37
|
let!(:old_value) { json['age'] }
|
38
|
+
|
38
39
|
before do
|
39
40
|
dummy.age
|
40
41
|
json['age'] = old_value + 100
|
@@ -52,36 +53,38 @@ describe Arstotzka do
|
|
52
53
|
expect(value).to be_a(House)
|
53
54
|
end
|
54
55
|
|
55
|
-
it 'creates the object with the
|
56
|
+
it 'creates the object with a method that is instantiated using the hash' do
|
56
57
|
expect(value.age).to eq(json['house']['age'])
|
57
|
-
expect(value.value).to eq(json['house']['value'])
|
58
|
-
expect(value.floors).to eq(json['house']['floors'])
|
59
58
|
end
|
60
59
|
|
61
60
|
context 'when dealing with an array' do
|
62
61
|
let(:attribute) { :games }
|
63
62
|
|
64
|
-
it 'returns an array
|
63
|
+
it 'returns an array' do
|
65
64
|
expect(value).to be_a(Array)
|
66
|
-
|
67
|
-
|
68
|
-
|
65
|
+
end
|
66
|
+
|
67
|
+
it 'returns an array of json wrapped' do
|
68
|
+
expect(value).to all(be_a(Game))
|
69
69
|
end
|
70
70
|
|
71
71
|
context 'when dealing with multiple level arrays' do
|
72
72
|
let(:attribute) { :games }
|
73
|
+
|
73
74
|
before do
|
74
75
|
json['games'].map! { |j| [j] }
|
75
76
|
end
|
76
77
|
|
77
|
-
it 'returns an array
|
78
|
+
it 'returns an array' do
|
78
79
|
expect(value).to be_a(Array)
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
|
80
|
+
end
|
81
|
+
|
82
|
+
it 'returns an array of arrays' do
|
83
|
+
expect(value).to all(be_a(Array))
|
84
|
+
end
|
85
|
+
|
86
|
+
it 'wraps each end element' do
|
87
|
+
expect(value).to all(all(be_a(Game)))
|
85
88
|
end
|
86
89
|
end
|
87
90
|
end
|
@@ -90,22 +93,19 @@ describe Arstotzka do
|
|
90
93
|
context 'when wrapping it with a class and caching' do
|
91
94
|
let(:attribute) { :old_house }
|
92
95
|
let!(:old_value) { json['oldHouse'] }
|
93
|
-
before do
|
94
|
-
dummy.old_house
|
95
|
-
json['oldHouse'] = {}
|
96
|
-
end
|
97
96
|
|
98
97
|
it 'returns an onject wrap' do
|
99
98
|
expect(value).to be_a(House)
|
100
99
|
end
|
101
100
|
|
102
101
|
it 'creates the object with the given json' do
|
103
|
-
expect(value.age).not_to eq(json['oldHouse']['age'])
|
104
102
|
expect(value.age).to eq(old_value['age'])
|
105
|
-
|
106
|
-
|
107
|
-
|
108
|
-
expect
|
103
|
+
end
|
104
|
+
|
105
|
+
it 'caches the resulting object' do
|
106
|
+
expect do
|
107
|
+
json['oldHouse'] = {}
|
108
|
+
end.not_to(change { dummy.old_house.age })
|
109
109
|
end
|
110
110
|
end
|
111
111
|
|
@@ -0,0 +1,20 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Arstotzka
|
4
|
+
module TypeCast
|
5
|
+
def to_car(hash)
|
6
|
+
Car.new(hash.symbolize_keys)
|
7
|
+
end
|
8
|
+
end
|
9
|
+
end
|
10
|
+
|
11
|
+
class CarCollector
|
12
|
+
include Arstotzka
|
13
|
+
|
14
|
+
attr_reader :json
|
15
|
+
|
16
|
+
expose :cars, full_path: 'cars.unit', type: :car
|
17
|
+
def initialize(hash)
|
18
|
+
@json = hash
|
19
|
+
end
|
20
|
+
end
|
@@ -0,0 +1,13 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
class TypeCaster
|
4
|
+
include Arstotzka
|
5
|
+
|
6
|
+
expose :age, type: :integer, json: :@hash
|
7
|
+
expose :payload, type: :string, json: :@hash
|
8
|
+
expose :price, type: :float, json: :@hash
|
9
|
+
|
10
|
+
def initialize(hash)
|
11
|
+
@hash = hash
|
12
|
+
end
|
13
|
+
end
|
@@ -1,6 +1,6 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
|
3
|
+
shared_examples 'a result that is type cast' do |types|
|
4
4
|
types.each do |type, clazz|
|
5
5
|
context "with #{type} type" do
|
6
6
|
let(:type) { type }
|
@@ -12,7 +12,7 @@ shared_context 'a result that is type cast' do |types|
|
|
12
12
|
end
|
13
13
|
end
|
14
14
|
|
15
|
-
|
15
|
+
shared_examples 'casts basic types' do
|
16
16
|
it_behaves_like 'a result that is type cast',
|
17
17
|
integer: Integer,
|
18
18
|
float: Float,
|