arstotzka 1.0.1 → 1.0.2
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 +1 -0
- data/.gitignore +2 -1
- data/.rubocop.yml +11 -0
- data/.rubocop_todo.yml +20 -0
- data/Gemfile +3 -2
- data/Guardfile +3 -2
- data/README.md +24 -5
- data/Rakefile +5 -3
- data/arstotzka.gemspec +18 -15
- data/arstotzka.jpg +0 -0
- data/lib/arstotzka.rb +2 -0
- data/lib/arstotzka/builder.rb +109 -47
- data/lib/arstotzka/class_methods.rb +34 -0
- data/lib/arstotzka/crawler.rb +86 -11
- data/lib/arstotzka/exception.rb +7 -2
- data/lib/arstotzka/fetcher.rb +93 -36
- data/lib/arstotzka/reader.rb +59 -11
- data/lib/arstotzka/type_cast.rb +24 -10
- data/lib/arstotzka/version.rb +3 -1
- data/lib/arstotzka/wrapper.rb +59 -34
- data/spec/integration/readme/default_spec.rb +2 -0
- data/spec/integration/readme/my_parser_spec.rb +2 -0
- data/spec/integration/yard/arstotzka/builder_spec.rb +63 -0
- data/spec/integration/yard/arstotzka/class_methods_spec.rb +49 -0
- data/spec/integration/yard/arstotzka/crawler_spec.rb +77 -0
- data/spec/integration/yard/arstotzka/fetcher_spec.rb +51 -0
- data/spec/integration/yard/arstotzka/reader_spec.rb +77 -0
- data/spec/integration/yard/arstotzka/wrapper_spec.rb +29 -0
- data/spec/lib/arstotzka/builder_spec.rb +6 -4
- data/spec/lib/arstotzka/crawler_spec.rb +30 -17
- data/spec/lib/arstotzka/fetcher_spec.rb +4 -2
- data/spec/lib/arstotzka/reader_spec.rb +13 -11
- data/spec/lib/arstotzka/wrapper_spec.rb +10 -10
- data/spec/lib/arstotzka_spec.rb +12 -8
- data/spec/spec_helper.rb +6 -2
- data/spec/support/fixture_helpers.rb +4 -2
- data/spec/support/models.rb +4 -3
- data/spec/support/models/account.rb +9 -0
- data/spec/support/models/arstotzka/dummy.rb +21 -17
- data/spec/support/models/arstotzka/fetcher/dummy.rb +7 -2
- data/spec/support/models/arstotzka/type_cast.rb +7 -4
- data/spec/support/models/arstotzka/wrapper/dummy.rb +10 -5
- data/spec/support/models/game.rb +2 -0
- data/spec/support/models/house.rb +2 -0
- data/spec/support/models/my_model.rb +9 -0
- data/spec/support/models/my_parser.rb +6 -5
- data/spec/support/models/person.rb +7 -1
- data/spec/support/models/star.rb +2 -0
- data/spec/support/models/star_gazer.rb +3 -2
- data/spec/support/models/transaction.rb +19 -0
- data/spec/support/shared_examples/wrapper.rb +6 -5
- metadata +64 -15
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
require 'spec_helper'
|
2
4
|
|
3
5
|
describe Arstotzka::Fetcher do
|
@@ -41,7 +43,7 @@ describe Arstotzka::Fetcher do
|
|
41
43
|
end
|
42
44
|
|
43
45
|
describe 'flatten options' do
|
44
|
-
let(:json) { [[[1,2],[3,4]],[[5,6],[7,8]]] }
|
46
|
+
let(:json) { [[[1, 2], [3, 4]], [[5, 6], [7, 8]]] }
|
45
47
|
|
46
48
|
context 'when flatten option is true' do
|
47
49
|
let(:options) { { flatten: true } }
|
@@ -70,7 +72,7 @@ describe Arstotzka::Fetcher do
|
|
70
72
|
|
71
73
|
describe 'after option' do
|
72
74
|
let(:instance) { MyParser.new(json) }
|
73
|
-
let(:json) { [
|
75
|
+
let(:json) { [100, 250, -25] }
|
74
76
|
let(:options) { { after: :sum } }
|
75
77
|
|
76
78
|
it 'applies after call ' do
|
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
require 'spec_helper'
|
2
4
|
|
3
5
|
shared_examples 'reader fetchin value' do
|
@@ -25,10 +27,10 @@ describe Arstotzka::Reader do
|
|
25
27
|
described_class.new(path: path, case_type: case_type)
|
26
28
|
end
|
27
29
|
|
28
|
-
let(:path) { %w
|
30
|
+
let(:path) { %w[user full_name] }
|
29
31
|
let(:json_file) { 'complete_person.json' }
|
30
32
|
let(:full_json) { load_json_fixture_file(json_file) }
|
31
|
-
let(:json) { full_json
|
33
|
+
let(:json) { full_json }
|
32
34
|
let(:sym_json) { json.symbolize_keys }
|
33
35
|
let(:case_type) { :snake }
|
34
36
|
let(:index) { 0 }
|
@@ -44,7 +46,7 @@ describe Arstotzka::Reader do
|
|
44
46
|
let(:index) { 1 }
|
45
47
|
|
46
48
|
context 'to snake_case' do
|
47
|
-
let(:path) { %w
|
49
|
+
let(:path) { %w[user FullName] }
|
48
50
|
let(:expected) { json['full_name'] }
|
49
51
|
|
50
52
|
it_behaves_like 'reader fetchin value'
|
@@ -52,7 +54,7 @@ describe Arstotzka::Reader do
|
|
52
54
|
|
53
55
|
context 'to upper_camel' do
|
54
56
|
let(:case_type) { :upper_camel }
|
55
|
-
let(:path) { %w
|
57
|
+
let(:path) { %w[user login_name] }
|
56
58
|
let(:expected) { json['LoginName'] }
|
57
59
|
|
58
60
|
it_behaves_like 'reader fetchin value'
|
@@ -60,7 +62,7 @@ describe Arstotzka::Reader do
|
|
60
62
|
|
61
63
|
context 'to lower_camel' do
|
62
64
|
let(:case_type) { :lower_camel }
|
63
|
-
let(:path) { %w
|
65
|
+
let(:path) { %w[user birth_date] }
|
64
66
|
let(:expected) { json['birthDate'] }
|
65
67
|
|
66
68
|
it_behaves_like 'reader fetchin value'
|
@@ -70,7 +72,7 @@ describe Arstotzka::Reader do
|
|
70
72
|
context 'when key is found but value is null' do
|
71
73
|
let(:json) { full_json['user'] }
|
72
74
|
let(:index) { 1 }
|
73
|
-
let(:path) { %w
|
75
|
+
let(:path) { %w[user password_reminder] }
|
74
76
|
|
75
77
|
it do
|
76
78
|
expect(subject.read(json, index)).to be_nil
|
@@ -84,7 +86,7 @@ describe Arstotzka::Reader do
|
|
84
86
|
end
|
85
87
|
|
86
88
|
context 'when json has both string and symble' do
|
87
|
-
let(:path) { %w
|
89
|
+
let(:path) { %w[key] }
|
88
90
|
let(:json) { { key: 'symbol', 'key' => 'string' } }
|
89
91
|
|
90
92
|
it 'fetches the string key first' do
|
@@ -94,7 +96,7 @@ describe Arstotzka::Reader do
|
|
94
96
|
end
|
95
97
|
|
96
98
|
context 'when the key is missing' do
|
97
|
-
let(:path) { %w
|
99
|
+
let(:path) { %w[age] }
|
98
100
|
|
99
101
|
it do
|
100
102
|
expect do
|
@@ -104,17 +106,17 @@ describe Arstotzka::Reader do
|
|
104
106
|
end
|
105
107
|
end
|
106
108
|
|
107
|
-
describe '
|
109
|
+
describe 'ended?' do
|
108
110
|
context 'when index is within path' do
|
109
111
|
let(:index) { 1 }
|
110
112
|
|
111
|
-
it { expect(subject.
|
113
|
+
it { expect(subject.ended?(index)).to be_falsey }
|
112
114
|
end
|
113
115
|
|
114
116
|
context 'when index is outside path' do
|
115
117
|
let(:index) { 2 }
|
116
118
|
|
117
|
-
it { expect(subject.
|
119
|
+
it { expect(subject.ended?(index)).to be_truthy }
|
118
120
|
end
|
119
121
|
end
|
120
122
|
end
|
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
require 'spec_helper'
|
2
4
|
|
3
5
|
describe Arstotzka::Wrapper do
|
@@ -79,20 +81,18 @@ describe Arstotzka::Wrapper do
|
|
79
81
|
context 'with blank value' do
|
80
82
|
let(:value) { '' }
|
81
83
|
|
82
|
-
it_behaves_like 'a result that is type cast',
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
}
|
84
|
+
it_behaves_like 'a result that is type cast',
|
85
|
+
integer: NilClass,
|
86
|
+
float: NilClass,
|
87
|
+
string: String
|
87
88
|
|
88
89
|
context 'when passing clazz parameter' do
|
89
90
|
let(:options) { { type: type, clazz: Arstotzka::Wrapper::Dummy } }
|
90
91
|
|
91
|
-
it_behaves_like 'a result that is type cast',
|
92
|
-
|
93
|
-
|
94
|
-
|
95
|
-
}
|
92
|
+
it_behaves_like 'a result that is type cast',
|
93
|
+
integer: NilClass,
|
94
|
+
float: NilClass,
|
95
|
+
string: Arstotzka::Wrapper::Dummy
|
96
96
|
end
|
97
97
|
end
|
98
98
|
|
data/spec/lib/arstotzka_spec.rb
CHANGED
@@ -1,9 +1,12 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
require 'spec_helper'
|
2
4
|
|
3
5
|
describe Arstotzka do
|
4
|
-
let(:
|
5
|
-
let(:
|
6
|
-
let(:
|
6
|
+
let(:dummy_class) { Arstotzka::Dummy }
|
7
|
+
let(:dummy) { dummy_class.new(json) }
|
8
|
+
let(:json) { load_json_fixture_file('arstotzka.json') }
|
9
|
+
let(:value) { dummy.public_send(attribute) }
|
7
10
|
|
8
11
|
context 'when parser is configured with no options' do
|
9
12
|
let(:attribute) { :id }
|
@@ -115,12 +118,13 @@ describe Arstotzka do
|
|
115
118
|
end
|
116
119
|
|
117
120
|
context 'when casting the result' do
|
118
|
-
|
119
|
-
expose :float_value, type: :float
|
120
|
-
end
|
121
|
-
|
122
|
-
let(:json) { { floatValue: '1' } }
|
121
|
+
let(:json) { { floatValue: '1' } }
|
123
122
|
let(:attribute) { :float_value }
|
123
|
+
let(:dummy_class) do
|
124
|
+
Class.new(Arstotzka::Dummy) do
|
125
|
+
expose :float_value, type: :float
|
126
|
+
end
|
127
|
+
end
|
124
128
|
|
125
129
|
it do
|
126
130
|
expect(value).to be_a(Float)
|
data/spec/spec_helper.rb
CHANGED
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
require 'simplecov'
|
2
4
|
SimpleCov.start do
|
3
5
|
add_filter 'spec/support/models/'
|
@@ -7,8 +9,8 @@ require 'pry-nav'
|
|
7
9
|
require 'arstotzka'
|
8
10
|
require 'safe_attribute_assignment'
|
9
11
|
|
10
|
-
support_files = File.expand_path(
|
11
|
-
Dir[support_files].sort.each { |file| require file
|
12
|
+
support_files = File.expand_path('spec/support/**/*.rb')
|
13
|
+
Dir[support_files].sort.each { |file| require file }
|
12
14
|
|
13
15
|
RSpec.configure do |config|
|
14
16
|
config.treat_symbols_as_metadata_keys_with_true_values = true
|
@@ -16,6 +18,8 @@ RSpec.configure do |config|
|
|
16
18
|
config.filter_run :focus
|
17
19
|
config.filter_run_excluding :integration unless ENV['ALL']
|
18
20
|
|
21
|
+
config.include Sinclair::Matchers
|
22
|
+
|
19
23
|
config.order = 'random'
|
20
24
|
|
21
25
|
config.before do
|
@@ -1,8 +1,10 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
require 'active_support'
|
2
4
|
|
3
5
|
module FixtureHelpers
|
4
6
|
def load_fixture_file(filename)
|
5
|
-
|
7
|
+
File.read(['./spec/', 'fixtures', filename].join('/'))
|
6
8
|
end
|
7
9
|
|
8
10
|
def load_json_fixture_file(filename)
|
@@ -12,7 +14,7 @@ module FixtureHelpers
|
|
12
14
|
private
|
13
15
|
|
14
16
|
def cached_json_fixture_file(filename)
|
15
|
-
|
17
|
+
ActiveSupport::JSON.decode(load_fixture_file(filename))
|
16
18
|
end
|
17
19
|
end
|
18
20
|
|
data/spec/support/models.rb
CHANGED
@@ -1,5 +1,6 @@
|
|
1
|
-
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
models = File.expand_path('spec/support/models/*.rb')
|
2
4
|
Dir[models].sort.each do |file|
|
3
|
-
autoload file.gsub(
|
5
|
+
autoload file.gsub(%r{.*\/(.*)\..*}, '\1').camelize.to_sym, file
|
4
6
|
end
|
5
|
-
|
@@ -1,23 +1,27 @@
|
|
1
|
-
|
2
|
-
include Arstotzka
|
3
|
-
attr_reader :json
|
1
|
+
# frozen_string_literal: true
|
4
2
|
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
expose :house, class: ::House
|
10
|
-
expose :old_house, class: ::House, cached: true
|
11
|
-
expose :games, class: ::Game
|
12
|
-
expose :games_filtered, class: ::Game, after: :filter_games, full_path: 'games'
|
3
|
+
module Arstotzka
|
4
|
+
class Dummy
|
5
|
+
include Arstotzka
|
6
|
+
attr_reader :json
|
13
7
|
|
14
|
-
|
15
|
-
|
16
|
-
|
8
|
+
expose :id
|
9
|
+
expose :name, path: 'user'
|
10
|
+
expose :father_name, full_path: 'father.name'
|
11
|
+
expose :age, cached: true
|
12
|
+
expose :house, class: ::House
|
13
|
+
expose :old_house, class: ::House, cached: true
|
14
|
+
expose :games, class: ::Game
|
15
|
+
expose :games_filtered, class: ::Game, after: :filter_games, full_path: 'games'
|
16
|
+
|
17
|
+
def initialize(json)
|
18
|
+
@json = json
|
19
|
+
end
|
17
20
|
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
+
def filter_games(games)
|
22
|
+
games.reject do |g|
|
23
|
+
g.publisher == 'sega'
|
24
|
+
end
|
21
25
|
end
|
22
26
|
end
|
23
27
|
end
|
@@ -1,7 +1,12 @@
|
|
1
|
-
|
2
|
-
|
3
|
-
|
4
|
-
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Arstotzka
|
4
|
+
class Wrapper
|
5
|
+
class Dummy
|
6
|
+
attr_reader :value
|
7
|
+
def initialize(value)
|
8
|
+
@value = value
|
9
|
+
end
|
10
|
+
end
|
5
11
|
end
|
6
12
|
end
|
7
|
-
|
data/spec/support/models/game.rb
CHANGED
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
class MyParser
|
2
4
|
include Arstotzka
|
3
5
|
|
@@ -6,7 +8,7 @@ class MyParser
|
|
6
8
|
expose :total_money, full_path: 'accounts.balance', after: :sum,
|
7
9
|
cached: true, type: :money_float
|
8
10
|
expose :total_owed, full_path: 'loans.value', after: :sum,
|
9
|
-
|
11
|
+
cached: true, type: :money_float
|
10
12
|
|
11
13
|
attr_reader :json
|
12
14
|
|
@@ -17,12 +19,11 @@ class MyParser
|
|
17
19
|
private
|
18
20
|
|
19
21
|
def sum(balances)
|
20
|
-
balances
|
22
|
+
balances&.sum
|
21
23
|
end
|
22
24
|
|
23
|
-
models = File.expand_path(
|
25
|
+
models = File.expand_path('spec/support/models/my_parser/*.rb')
|
24
26
|
Dir[models].each do |file|
|
25
|
-
autoload file.gsub(
|
27
|
+
autoload file.gsub(%r{.*\/(.*)\..*}, '\1').camelize.to_sym, file
|
26
28
|
end
|
27
29
|
end
|
28
|
-
|
data/spec/support/models/star.rb
CHANGED
@@ -1,8 +1,10 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
class StarGazer
|
2
4
|
include Arstotzka
|
3
5
|
|
4
6
|
expose :favorite_star, full_path: 'universe.star',
|
5
|
-
|
7
|
+
default: { name: 'Sun' }, class: ::Star
|
6
8
|
|
7
9
|
attr_reader :json
|
8
10
|
|
@@ -10,4 +12,3 @@ class StarGazer
|
|
10
12
|
@json = json
|
11
13
|
end
|
12
14
|
end
|
13
|
-
|
@@ -0,0 +1,19 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
class Transaction
|
4
|
+
attr_reader :value, :type
|
5
|
+
|
6
|
+
def initialize(value:, type:)
|
7
|
+
@value = value
|
8
|
+
@type = type
|
9
|
+
end
|
10
|
+
|
11
|
+
def positive?
|
12
|
+
type == 'income'
|
13
|
+
end
|
14
|
+
|
15
|
+
def ==(other)
|
16
|
+
return false unless other.class == self.class
|
17
|
+
other.value == value && other.type == type
|
18
|
+
end
|
19
|
+
end
|