arstotzka 1.0.1 → 1.0.2

Sign up to get free protection for your applications and to get access to all the features.
Files changed (53) hide show
  1. checksums.yaml +4 -4
  2. data/.circleci/config.yml +1 -0
  3. data/.gitignore +2 -1
  4. data/.rubocop.yml +11 -0
  5. data/.rubocop_todo.yml +20 -0
  6. data/Gemfile +3 -2
  7. data/Guardfile +3 -2
  8. data/README.md +24 -5
  9. data/Rakefile +5 -3
  10. data/arstotzka.gemspec +18 -15
  11. data/arstotzka.jpg +0 -0
  12. data/lib/arstotzka.rb +2 -0
  13. data/lib/arstotzka/builder.rb +109 -47
  14. data/lib/arstotzka/class_methods.rb +34 -0
  15. data/lib/arstotzka/crawler.rb +86 -11
  16. data/lib/arstotzka/exception.rb +7 -2
  17. data/lib/arstotzka/fetcher.rb +93 -36
  18. data/lib/arstotzka/reader.rb +59 -11
  19. data/lib/arstotzka/type_cast.rb +24 -10
  20. data/lib/arstotzka/version.rb +3 -1
  21. data/lib/arstotzka/wrapper.rb +59 -34
  22. data/spec/integration/readme/default_spec.rb +2 -0
  23. data/spec/integration/readme/my_parser_spec.rb +2 -0
  24. data/spec/integration/yard/arstotzka/builder_spec.rb +63 -0
  25. data/spec/integration/yard/arstotzka/class_methods_spec.rb +49 -0
  26. data/spec/integration/yard/arstotzka/crawler_spec.rb +77 -0
  27. data/spec/integration/yard/arstotzka/fetcher_spec.rb +51 -0
  28. data/spec/integration/yard/arstotzka/reader_spec.rb +77 -0
  29. data/spec/integration/yard/arstotzka/wrapper_spec.rb +29 -0
  30. data/spec/lib/arstotzka/builder_spec.rb +6 -4
  31. data/spec/lib/arstotzka/crawler_spec.rb +30 -17
  32. data/spec/lib/arstotzka/fetcher_spec.rb +4 -2
  33. data/spec/lib/arstotzka/reader_spec.rb +13 -11
  34. data/spec/lib/arstotzka/wrapper_spec.rb +10 -10
  35. data/spec/lib/arstotzka_spec.rb +12 -8
  36. data/spec/spec_helper.rb +6 -2
  37. data/spec/support/fixture_helpers.rb +4 -2
  38. data/spec/support/models.rb +4 -3
  39. data/spec/support/models/account.rb +9 -0
  40. data/spec/support/models/arstotzka/dummy.rb +21 -17
  41. data/spec/support/models/arstotzka/fetcher/dummy.rb +7 -2
  42. data/spec/support/models/arstotzka/type_cast.rb +7 -4
  43. data/spec/support/models/arstotzka/wrapper/dummy.rb +10 -5
  44. data/spec/support/models/game.rb +2 -0
  45. data/spec/support/models/house.rb +2 -0
  46. data/spec/support/models/my_model.rb +9 -0
  47. data/spec/support/models/my_parser.rb +6 -5
  48. data/spec/support/models/person.rb +7 -1
  49. data/spec/support/models/star.rb +2 -0
  50. data/spec/support/models/star_gazer.rb +3 -2
  51. data/spec/support/models/transaction.rb +19 -0
  52. data/spec/support/shared_examples/wrapper.rb +6 -5
  53. 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) { [ 100, 250, -25] }
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(user full_name) }
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(user FullName) }
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(user login_name) }
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(user birth_date) }
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(user password_reminder) }
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(key) }
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(age) }
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 'is_ended?' do
109
+ describe 'ended?' do
108
110
  context 'when index is within path' do
109
111
  let(:index) { 1 }
110
112
 
111
- it { expect(subject.is_ended?(index)).to be_falsey }
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.is_ended?(index)).to be_truthy }
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
- integer: NilClass,
84
- float: NilClass,
85
- string: String
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
- integer: NilClass,
93
- float: NilClass,
94
- string: Arstotzka::Wrapper::Dummy
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
 
@@ -1,9 +1,12 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'spec_helper'
2
4
 
3
5
  describe Arstotzka do
4
- let(:dummy) { Arstotzka::Dummy.new(json) }
5
- let(:json) { load_json_fixture_file('arstotzka.json') }
6
- let(:value) { dummy.public_send(attribute) }
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
- class Arstotzka::Dummy
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)
@@ -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("spec/support/**/*.rb")
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
- File.read (['./spec/', 'fixtures', filename].join('/'))
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
- ActiveSupport::JSON.decode(load_fixture_file(filename))
17
+ ActiveSupport::JSON.decode(load_fixture_file(filename))
16
18
  end
17
19
  end
18
20
 
@@ -1,5 +1,6 @@
1
- models = File.expand_path("spec/support/models/*.rb")
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(/.*\/(.*)\..*/, '\1').camelize.to_sym, file
5
+ autoload file.gsub(%r{.*\/(.*)\..*}, '\1').camelize.to_sym, file
4
6
  end
5
-
@@ -0,0 +1,9 @@
1
+ # frozen_string_literal: true
2
+
3
+ class Account
4
+ private
5
+
6
+ def filter_income(transactions)
7
+ transactions.select(&:positive?)
8
+ end
9
+ end
@@ -1,23 +1,27 @@
1
- class Arstotzka::Dummy
2
- include Arstotzka
3
- attr_reader :json
1
+ # frozen_string_literal: true
4
2
 
5
- expose :id
6
- expose :name, path: 'user'
7
- expose :father_name, full_path: 'father.name'
8
- expose :age, cached: true
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
- def initialize(json)
15
- @json = json
16
- end
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
- def filter_games(games)
19
- games.select do |g|
20
- g.publisher != 'sega'
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,3 +1,8 @@
1
- class Arstotzka::Fetcher::Dummy
2
- end
1
+ # frozen_string_literal: true
3
2
 
3
+ module Arstotzka
4
+ class Fetcher
5
+ class Dummy
6
+ end
7
+ end
8
+ end
@@ -1,6 +1,9 @@
1
- module Arstotzka::TypeCast
2
- def to_money_float(value)
3
- value.gsub(/\$ */, '').to_f
1
+ # frozen_string_literal: true
2
+
3
+ module Arstotzka
4
+ module TypeCast
5
+ def to_money_float(value)
6
+ value.gsub(/\$ */, '').to_f
7
+ end
4
8
  end
5
9
  end
6
-
@@ -1,7 +1,12 @@
1
- class Arstotzka::Wrapper::Dummy
2
- attr_reader :value
3
- def initialize(value)
4
- @value = value
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
-
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  class Game
2
4
  include Arstotzka
3
5
  include SafeAttributeAssignment
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  class House
2
4
  include Arstotzka
3
5
  include ::SafeAttributeAssignment
@@ -0,0 +1,9 @@
1
+ # frozen_string_literal: true
2
+
3
+ class MyModel
4
+ attr_reader :json
5
+
6
+ def initialize(json)
7
+ @json = json
8
+ end
9
+ end
@@ -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
- cached: true, type: :money_float
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.sum if balances
22
+ balances&.sum
21
23
  end
22
24
 
23
- models = File.expand_path("spec/support/models/my_parser/*.rb")
25
+ models = File.expand_path('spec/support/models/my_parser/*.rb')
24
26
  Dir[models].each do |file|
25
- autoload file.gsub(/.*\/(.*)\..*/, '\1').camelize.to_sym, file
27
+ autoload file.gsub(%r{.*\/(.*)\..*}, '\1').camelize.to_sym, file
26
28
  end
27
29
  end
28
-
@@ -1,8 +1,14 @@
1
+ # frozen_string_literal: true
2
+
1
3
  class Person
2
4
  attr_reader :name
3
5
 
4
6
  def initialize(name)
5
7
  @name = name
6
8
  end
7
- end
8
9
 
10
+ def ==(other)
11
+ return false unless other.class == self.class
12
+ other.name == name
13
+ end
14
+ end
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  class Star
2
4
  attr_reader :name
3
5
 
@@ -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
- default: { name: 'Sun' }, class: ::Star
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