iex-ruby-client 1.1.1 → 1.4.1

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.
Files changed (74) hide show
  1. checksums.yaml +4 -4
  2. data/.env.sample +2 -0
  3. data/.github/FUNDING.yml +1 -0
  4. data/.rubocop_todo.yml +0 -8
  5. data/CHANGELOG.md +49 -12
  6. data/Dangerfile +2 -2
  7. data/Gemfile +3 -2
  8. data/README.md +276 -20
  9. data/RELEASING.md +2 -2
  10. data/iex-ruby-client.gemspec +2 -1
  11. data/lib/iex/api.rb +8 -1
  12. data/lib/iex/api/client.rb +15 -2
  13. data/lib/iex/api/config/client.rb +52 -0
  14. data/lib/iex/api/config/logger.rb +35 -0
  15. data/lib/iex/cloud/connection.rb +22 -19
  16. data/lib/iex/cloud/response.rb +1 -1
  17. data/lib/iex/endpoints/advanced_stats.rb +11 -0
  18. data/lib/iex/endpoints/balance_sheet.rb +13 -0
  19. data/lib/iex/endpoints/cash_flow.rb +13 -0
  20. data/lib/iex/endpoints/historial_prices.rb +30 -0
  21. data/lib/iex/endpoints/ref_data.rb +27 -0
  22. data/lib/iex/endpoints/stock_market.rb +11 -0
  23. data/lib/iex/resources.rb +6 -0
  24. data/lib/iex/resources/advanced_stats.rb +84 -0
  25. data/lib/iex/resources/balance_sheet.rb +60 -0
  26. data/lib/iex/resources/cash_flow.rb +43 -0
  27. data/lib/iex/resources/historical_prices.rb +31 -0
  28. data/lib/iex/resources/income.rb +2 -0
  29. data/lib/iex/resources/key_stats.rb +1 -1
  30. data/lib/iex/resources/news.rb +3 -0
  31. data/lib/iex/resources/quote.rb +12 -2
  32. data/lib/iex/resources/resource.rb +12 -0
  33. data/lib/iex/resources/symbol.rb +10 -0
  34. data/lib/iex/resources/symbols.rb +19 -0
  35. data/lib/iex/version.rb +1 -1
  36. data/spec/fixtures/iex/advanced_stats/invalid.yml +50 -0
  37. data/spec/fixtures/iex/advanced_stats/msft.yml +57 -0
  38. data/spec/fixtures/iex/balance_sheet/invalid.yml +50 -0
  39. data/spec/fixtures/iex/balance_sheet/msft.yml +56 -0
  40. data/spec/fixtures/iex/cash_flow/invalid.yml +50 -0
  41. data/spec/fixtures/iex/cash_flow/msft.yml +56 -0
  42. data/spec/fixtures/iex/historical_prices/abcd.yml +56 -0
  43. data/spec/fixtures/iex/historical_prices/invalid.yml +50 -0
  44. data/spec/fixtures/iex/historical_prices/invalid_date.yml +50 -0
  45. data/spec/fixtures/iex/historical_prices/invalid_range.yml +47 -0
  46. data/spec/fixtures/iex/historical_prices/msft.yml +79 -0
  47. data/spec/fixtures/iex/historical_prices/msft_5d.yml +61 -0
  48. data/spec/fixtures/iex/historical_prices/msft_date_and_chart_by_day.yml +57 -0
  49. data/spec/fixtures/iex/historical_prices/msft_specific_date_trimmed.yml +445 -0
  50. data/spec/fixtures/iex/income/msft.yml +54 -51
  51. data/spec/fixtures/iex/ref-data/exchange_symbols.yml +1926 -0
  52. data/spec/fixtures/iex/ref-data/isin.yml +9 -9
  53. data/spec/fixtures/iex/ref-data/isin_mapped.yml +57 -0
  54. data/spec/fixtures/iex/ref-data/symbols.yml +9002 -0
  55. data/spec/fixtures/iex/ref-data/wrong_isin_mapped.yml +57 -0
  56. data/spec/fixtures/iex/stock_market/list_mostactive.yml +76 -0
  57. data/spec/iex/client_spec.rb +96 -13
  58. data/spec/iex/config/client_spec.rb +49 -0
  59. data/spec/iex/config/logger_spec.rb +46 -0
  60. data/spec/iex/endpoints/advanced_stats_spec.rb +110 -0
  61. data/spec/iex/endpoints/balance_sheet_spec.rb +80 -0
  62. data/spec/iex/endpoints/cash_flow_spec.rb +59 -0
  63. data/spec/iex/endpoints/historical_prices_spec.rb +206 -0
  64. data/spec/iex/endpoints/income_spec.rb +31 -29
  65. data/spec/iex/endpoints/key_stats_spec.rb +1 -0
  66. data/spec/iex/endpoints/news_spec.rb +3 -0
  67. data/spec/iex/endpoints/quote_spec.rb +2 -0
  68. data/spec/iex/endpoints/ref_data_spec.rb +103 -8
  69. data/spec/iex/endpoints/stock_market_spec.rb +14 -0
  70. data/spec/iex/resources/resource_spec.rb +36 -0
  71. data/spec/spec_helper.rb +3 -3
  72. metadata +74 -9
  73. data/lib/iex/api/config.rb +0 -47
  74. data/spec/iex/config_spec.rb +0 -22
@@ -0,0 +1,80 @@
1
+ require 'spec_helper'
2
+
3
+ describe IEX::Resources::BalanceSheet do
4
+ include_context 'client'
5
+
6
+ context 'general information', vcr: { cassette_name: 'balance_sheet/msft' } do
7
+ subject do
8
+ client.balance_sheet('MSFT')
9
+ end
10
+ let(:balance_sheet) { subject.first }
11
+
12
+ it 'fetches balance sheet' do
13
+ expect(subject.size).to eq 1
14
+ expect(balance_sheet.report_date).to eq '2020-09-30'
15
+ expect(balance_sheet.fiscal_date).to eq '2020-09-30'
16
+ expect(balance_sheet.currency).to eq 'USD'
17
+ expect(balance_sheet.current_cash).to eq 17_205_000_000
18
+ expect(balance_sheet.current_cash_dollar).to eq '$17,205,000,000'
19
+ expect(balance_sheet.short_term_investments).to eq 120_772_000_000
20
+ expect(balance_sheet.short_term_investments_dollar).to eq '$120,772,000,000'
21
+ expect(balance_sheet.receivables).to eq 22_851_000_000
22
+ expect(balance_sheet.receivables_dollar).to eq '$22,851,000,000'
23
+ expect(balance_sheet.inventory).to eq 2_705_000_000
24
+ expect(balance_sheet.inventory_dollar).to eq '$2,705,000,000'
25
+ expect(balance_sheet.other_current_assets).to eq 13_544_000_000
26
+ expect(balance_sheet.other_current_assets_dollar).to eq '$13,544,000,000'
27
+ expect(balance_sheet.current_assets).to eq 177_077_000_000
28
+ expect(balance_sheet.current_assets_dollar).to eq '$177,077,000,000'
29
+ expect(balance_sheet.long_term_investments).to eq 3_196_000_000
30
+ expect(balance_sheet.long_term_investments_dollar).to eq '$3,196,000,000'
31
+ expect(balance_sheet.property_plant_equipment).to eq 56_974_000_000
32
+ expect(balance_sheet.property_plant_equipment_dollar).to eq '$56,974,000,000'
33
+ expect(balance_sheet.goodwill).to eq 43_890_000_000
34
+ expect(balance_sheet.goodwill_dollar).to eq '$43,890,000,000'
35
+ expect(balance_sheet.intangible_assets).to eq 6_923_000_000
36
+ expect(balance_sheet.intangible_assets_dollar).to eq '$6,923,000,000'
37
+ expect(balance_sheet.other_assets).to eq 12_941_000_000
38
+ expect(balance_sheet.other_assets_dollar).to eq '$12,941,000,000'
39
+ expect(balance_sheet.total_assets).to eq 301_001_000_000
40
+ expect(balance_sheet.total_assets_dollar).to eq '$301,001,000,000'
41
+ expect(balance_sheet.accounts_payable).to eq 12_509_000_000
42
+ expect(balance_sheet.accounts_payable_dollar).to eq '$12,509,000,000'
43
+ expect(balance_sheet.current_long_term_debt).to eq 7_093_000_000
44
+ expect(balance_sheet.current_long_term_debt_dollar).to eq '$7,093,000,000'
45
+ expect(balance_sheet.other_current_liabilities).to eq 46_326_000_000
46
+ expect(balance_sheet.other_current_liabilities_dollar).to eq '$46,326,000,000'
47
+ expect(balance_sheet.total_current_liabilities).to eq 70_056_000_000
48
+ expect(balance_sheet.total_current_liabilities_dollar).to eq '$70,056,000,000'
49
+ expect(balance_sheet.long_term_debt).to eq 74_379_000_000
50
+ expect(balance_sheet.long_term_debt_dollar).to eq '$74,379,000,000'
51
+ expect(balance_sheet.other_liabilities).to eq 32_987_000_000
52
+ expect(balance_sheet.other_liabilities_dollar).to eq '$32,987,000,000'
53
+ expect(balance_sheet.minority_interest).to eq 0
54
+ expect(balance_sheet.minority_interest_dollar).to eq '$0'
55
+ expect(balance_sheet.total_liabilities).to eq 177_609_000_000
56
+ expect(balance_sheet.total_liabilities_dollar).to eq '$177,609,000,000'
57
+ expect(balance_sheet.common_stock).to eq 7_564_000_000
58
+ expect(balance_sheet.retained_earnings).to eq 39_193_000_000
59
+ expect(balance_sheet.retained_earnings_dollar).to eq '$39,193,000,000'
60
+ expect(balance_sheet.treasury_stock).to eq nil
61
+ expect(balance_sheet.treasury_stock_dollar).to eq nil
62
+ expect(balance_sheet.capital_surplus).to eq nil
63
+ expect(balance_sheet.capital_surplus_dollar).to eq nil
64
+ expect(balance_sheet.shareholder_equity).to eq 123_392_000_000
65
+ expect(balance_sheet.shareholder_equity_dollar).to eq '$123,392,000,000'
66
+ expect(balance_sheet.net_tangible_assets).to eq 17_585_000_000
67
+ expect(balance_sheet.net_tangible_assets_dollar).to eq '$17,585,000,000'
68
+ end
69
+ end
70
+
71
+ context 'invalid symbol', vcr: { cassette_name: 'balance_sheet/invalid' } do
72
+ subject do
73
+ client.balance_sheet('INVALID')
74
+ end
75
+
76
+ it 'fails with SymbolNotFoundError' do
77
+ expect { subject }.to raise_error IEX::Errors::SymbolNotFoundError, 'Symbol INVALID Not Found'
78
+ end
79
+ end
80
+ end
@@ -0,0 +1,59 @@
1
+ require 'spec_helper'
2
+
3
+ describe IEX::Resources::CashFlow do
4
+ include_context 'client'
5
+
6
+ context 'general information', vcr: { cassette_name: 'cash_flow/msft' } do
7
+ subject do
8
+ client.cash_flow('MSFT')
9
+ end
10
+ let(:cash_flow) { subject.first }
11
+
12
+ it 'fetches cash flow statement' do
13
+ expect(subject.size).to eq 1
14
+ expect(cash_flow.report_date).to eq '2020-09-30'
15
+ expect(cash_flow.fiscal_date).to eq '2020-09-30'
16
+ expect(cash_flow.currency).to eq 'USD'
17
+ expect(cash_flow.net_income).to eq 13_893_000_000
18
+ expect(cash_flow.net_income_dollar).to eq '$13,893,000,000'
19
+ expect(cash_flow.depreciation).to eq 2_645_000_000
20
+ expect(cash_flow.depreciation_dollar).to eq '$2,645,000,000'
21
+ expect(cash_flow.changes_in_receivables).to eq 9_160_000_000
22
+ expect(cash_flow.changes_in_receivables_dollar).to eq '$9,160,000,000'
23
+ expect(cash_flow.changes_in_inventories).to eq(-808_000_000)
24
+ expect(cash_flow.changes_in_inventories_dollar).to eq '$-808,000,000'
25
+ expect(cash_flow.cash_change).to eq 3_629_000_000
26
+ expect(cash_flow.cash_change_dollar).to eq '$3,629,000,000'
27
+ expect(cash_flow.cash_flow).to eq 19_335_000_000
28
+ expect(cash_flow.cash_flow_dollar).to eq '$19,335,000,000'
29
+ expect(cash_flow.capital_expenditures).to eq(-4_907_000_000)
30
+ expect(cash_flow.capital_expenditures_dollar).to eq '$-4,907,000,000'
31
+ expect(cash_flow.investments).to eq 2_100_000_000
32
+ expect(cash_flow.investments_dollar).to eq '$2,100,000,000'
33
+ expect(cash_flow.investing_activity_other).to eq(-2_083_000_000)
34
+ expect(cash_flow.investing_activity_other_dollar).to eq '$-2,083,000,000'
35
+ expect(cash_flow.total_investing_cash_flows).to eq(-5_371_000_000)
36
+ expect(cash_flow.total_investing_cash_flows_dollar).to eq '$-5,371,000,000'
37
+ expect(cash_flow.dividends_paid).to eq(-3_856_000_000)
38
+ expect(cash_flow.dividends_paid_dollar).to eq '$-3,856,000,000'
39
+ expect(cash_flow.net_borrowings).to eq nil
40
+ expect(cash_flow.net_borrowings_dollar).to eq nil
41
+ expect(cash_flow.other_financing_cash_flows).to eq(-235_000_000)
42
+ expect(cash_flow.other_financing_cash_flows_dollar).to eq '$-235,000,000'
43
+ expect(cash_flow.cash_flow_financing).to eq(-10_289_000_000)
44
+ expect(cash_flow.cash_flow_financing_dollar).to eq '$-10,289,000,000'
45
+ expect(cash_flow.exchange_rate_effect).to eq(-46_000_000)
46
+ expect(cash_flow.exchange_rate_effect_dollar).to eq '$-46,000,000'
47
+ end
48
+ end
49
+
50
+ context 'invalid symbol', vcr: { cassette_name: 'cash_flow/invalid' } do
51
+ subject do
52
+ client.cash_flow('INVALID')
53
+ end
54
+
55
+ it 'fails with SymbolNotFoundError' do
56
+ expect { subject }.to raise_error IEX::Errors::SymbolNotFoundError, 'Symbol INVALID Not Found'
57
+ end
58
+ end
59
+ end
@@ -0,0 +1,206 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'spec_helper'
4
+
5
+ describe IEX::Resources::HistorialPrices do
6
+ include_context 'client'
7
+
8
+ context 'known symbol' do
9
+ context 'with valid params' do
10
+ context 'with defaults', vcr: { cassette_name: 'historical_prices/msft' } do
11
+ subject do
12
+ client.historical_prices('MSFT')
13
+ end
14
+ let(:historical_price) { subject.first }
15
+
16
+ it 'retrieves historical prices' do
17
+ expect(subject.size).to eq 23
18
+ expect(historical_price.date).to eq '2020-10-07'
19
+ expect(historical_price.open).to eq 207.06
20
+ expect(historical_price.open_dollar).to eq '$207.06'
21
+ expect(historical_price.close).to eq 209.83
22
+ expect(historical_price.close_dollar).to eq '$209.83'
23
+ expect(historical_price.high).to eq 210.11
24
+ expect(historical_price.high_dollar).to eq '$210.11'
25
+ expect(historical_price.low).to eq 206.72
26
+ expect(historical_price.low_dollar).to eq '$206.72'
27
+ expect(historical_price.volume).to eq 25_681_054
28
+ expect(historical_price.u_open).to eq 207.06
29
+ expect(historical_price.u_open_dollar).to eq '$207.06'
30
+ expect(historical_price.u_close).to eq 209.83
31
+ expect(historical_price.u_close_dollar).to eq '$209.83'
32
+ expect(historical_price.u_low).to eq 206.72
33
+ expect(historical_price.u_low_dollar).to eq '$206.72'
34
+ expect(historical_price.u_high).to eq 210.11
35
+ expect(historical_price.u_high_dollar).to eq '$210.11'
36
+ expect(historical_price.u_volume).to eq 25_681_054
37
+ expect(historical_price.change).to eq 0
38
+ expect(historical_price.change_percent).to eq 0
39
+ expect(historical_price.change_percent_s).to eq '+0.00%'
40
+ expect(historical_price.label).to eq 'Oct 7'
41
+ expect(historical_price.change_over_time).to eq 0
42
+ expect(historical_price.change_over_time_s).to eq '+0.00%'
43
+ end
44
+ end
45
+
46
+ context 'with a valid range provided', vcr: { cassette_name: 'historical_prices/msft_5d' } do
47
+ subject { client.historical_prices('MSFT', range: '5d') }
48
+ let(:historical_price) { subject.last }
49
+
50
+ it 'retrieves historical prices' do
51
+ expect(subject.size).to eq 5
52
+ expect(historical_price.date).to eq '2020-11-10'
53
+ expect(historical_price.open).to eq 214.50
54
+ expect(historical_price.open_dollar).to eq '$214.50'
55
+ expect(historical_price.close).to eq 211.01
56
+ expect(historical_price.close_dollar).to eq '$211.01'
57
+ expect(historical_price.high).to eq 216.50
58
+ expect(historical_price.high_dollar).to eq '$216.50'
59
+ expect(historical_price.low).to eq 209.72
60
+ expect(historical_price.low_dollar).to eq '$209.72'
61
+ expect(historical_price.volume).to eq 44_045_120
62
+ expect(historical_price.u_open).to eq 214.50
63
+ expect(historical_price.u_open_dollar).to eq '$214.50'
64
+ expect(historical_price.u_close).to eq 211.01
65
+ expect(historical_price.u_close_dollar).to eq '$211.01'
66
+ expect(historical_price.u_low).to eq 209.72
67
+ expect(historical_price.u_low_dollar).to eq '$209.72'
68
+ expect(historical_price.u_high).to eq 216.50
69
+ expect(historical_price.u_high_dollar).to eq '$216.50'
70
+ expect(historical_price.u_volume).to eq 44_045_120
71
+ expect(historical_price.change).to eq(-7.38)
72
+ expect(historical_price.change_percent).to eq(-3.3793)
73
+ expect(historical_price.change_percent_s).to eq '-3.38%'
74
+ expect(historical_price.label).to eq 'Nov 10'
75
+ expect(historical_price.change_over_time).to eq(-0.024863)
76
+ expect(historical_price.change_over_time_s).to eq '-0.02%'
77
+ end
78
+ end
79
+
80
+ context 'with a range provided for a specific date (passed as a Date object) and chartByDay param',
81
+ vcr: { cassette_name: 'historical_prices/msft_date_and_chart_by_day' } do
82
+ options = { range: 'date', date: Date.parse('2020-11-10'), chartByDay: 'true' }
83
+ subject { client.historical_prices('MSFT', options) }
84
+ let(:historical_price) { subject.first }
85
+
86
+ it 'retrieves historical prices' do
87
+ expect(subject.size).to eq 1
88
+ expect(historical_price.date).to eq '2020-11-10'
89
+ expect(historical_price.open).to eq 214.50
90
+ expect(historical_price.open_dollar).to eq '$214.50'
91
+ expect(historical_price.close).to eq 211.01
92
+ expect(historical_price.close_dollar).to eq '$211.01'
93
+ expect(historical_price.high).to eq 216.50
94
+ expect(historical_price.high_dollar).to eq '$216.50'
95
+ expect(historical_price.low).to eq 209.72
96
+ expect(historical_price.low_dollar).to eq '$209.72'
97
+ expect(historical_price.volume).to eq 44_045_120
98
+ expect(historical_price.u_open).to eq 214.50
99
+ expect(historical_price.u_open_dollar).to eq '$214.50'
100
+ expect(historical_price.u_close).to eq 211.01
101
+ expect(historical_price.u_close_dollar).to eq '$211.01'
102
+ expect(historical_price.u_low).to eq 209.72
103
+ expect(historical_price.u_low_dollar).to eq '$209.72'
104
+ expect(historical_price.u_high).to eq 216.50
105
+ expect(historical_price.u_high_dollar).to eq '$216.50'
106
+ expect(historical_price.u_volume).to eq 44_045_120
107
+ expect(historical_price.change).to eq(-7.38)
108
+ expect(historical_price.change_percent).to eq(-3.3793)
109
+ expect(historical_price.change_percent_s).to eq '-3.38%'
110
+ expect(historical_price.label).to eq 'Nov 10'
111
+ expect(historical_price.change_over_time).to eq(-0.033793)
112
+ expect(historical_price.change_over_time_s).to eq '-0.03%'
113
+ end
114
+ end
115
+
116
+ context 'with a range provided for a specific date (passed as a string) and chartByDay param',
117
+ vcr: { cassette_name: 'historical_prices/msft_date_and_chart_by_day' } do
118
+ options = { range: 'date', date: '20201110', chartByDay: 'true' }
119
+ subject { client.historical_prices('MSFT', options) }
120
+ let(:historical_price) { subject.first }
121
+
122
+ it 'retrieves historical prices' do
123
+ expect(subject.size).to eq 1
124
+ expect(historical_price.date).to eq '2020-11-10'
125
+ expect(historical_price.open).to eq 214.50
126
+ expect(historical_price.open_dollar).to eq '$214.50'
127
+ expect(historical_price.close).to eq 211.01
128
+ expect(historical_price.close_dollar).to eq '$211.01'
129
+ expect(historical_price.high).to eq 216.50
130
+ expect(historical_price.high_dollar).to eq '$216.50'
131
+ expect(historical_price.low).to eq 209.72
132
+ expect(historical_price.low_dollar).to eq '$209.72'
133
+ expect(historical_price.volume).to eq 44_045_120
134
+ expect(historical_price.u_open).to eq 214.50
135
+ expect(historical_price.u_open_dollar).to eq '$214.50'
136
+ expect(historical_price.u_close).to eq 211.01
137
+ expect(historical_price.u_close_dollar).to eq '$211.01'
138
+ expect(historical_price.u_low).to eq 209.72
139
+ expect(historical_price.u_low_dollar).to eq '$209.72'
140
+ expect(historical_price.u_high).to eq 216.50
141
+ expect(historical_price.u_high_dollar).to eq '$216.50'
142
+ expect(historical_price.u_volume).to eq 44_045_120
143
+ expect(historical_price.change).to eq(-7.38)
144
+ expect(historical_price.change_percent).to eq(-3.3793)
145
+ expect(historical_price.change_percent_s).to eq '-3.38%'
146
+ expect(historical_price.label).to eq 'Nov 10'
147
+ expect(historical_price.change_over_time).to eq(-0.033793)
148
+ expect(historical_price.change_over_time_s).to eq '-0.03%'
149
+ end
150
+ end
151
+ end
152
+
153
+ context 'with invalid params' do
154
+ context 'with an invalid range', vcr: { cassette_name: 'historical_prices/invalid_range' } do
155
+ subject { client.historical_prices('MSFT', range: 'invalid') }
156
+
157
+ it 'fails with ArgumentError' do
158
+ expect { subject }.to raise_error IEX::Errors::PermissionDeniedError
159
+ end
160
+ end
161
+
162
+ context "with a range as 'date' but without a date param" do
163
+ subject { client.historical_prices('MSFT', range: 'date') }
164
+
165
+ it 'fails with ArgumentError' do
166
+ expect { subject }.to raise_error ArgumentError
167
+ end
168
+ end
169
+
170
+ context "with a range as 'date' but without chartByDay query param" do
171
+ subject { client.historical_prices('MSFT', range: 'date', date: Date.parse('2020-11-10')) }
172
+
173
+ it 'fails with ArgumentError' do
174
+ expect { subject }.to raise_error ArgumentError
175
+ end
176
+ end
177
+
178
+ context "with a range as 'date' but without date as a Date object that is incorrectly formatted",
179
+ vcr: { cassette_name: 'historical_prices/invalid_date' } do
180
+ subject { client.historical_prices('MSFT', range: 'date', date: '2020-11-10', chartByDay: 'true') }
181
+
182
+ it 'fails with ArgumentError' do
183
+ expect { subject }.to raise_error IEX::Errors::ClientError
184
+ end
185
+ end
186
+ end
187
+ end
188
+
189
+ context 'no result', vcr: { cassette_name: 'historical_prices/abcd' } do
190
+ subject do
191
+ client.historical_prices('abcd')
192
+ end
193
+ it 'returns empty array' do
194
+ expect(subject).to eq []
195
+ end
196
+ end
197
+
198
+ context 'invalid symbol', vcr: { cassette_name: 'historical_prices/invalid' } do
199
+ subject do
200
+ client.historical_prices('INVALID')
201
+ end
202
+ it 'fails with SymbolNotFoundError' do
203
+ expect { subject }.to raise_error IEX::Errors::SymbolNotFoundError, 'Symbol INVALID Not Found'
204
+ end
205
+ end
206
+ end
@@ -14,36 +14,38 @@ describe IEX::Resources::Income do
14
14
 
15
15
  it 'retrieves income statement' do
16
16
  expect(subject.size).to eq 1
17
- expect(income.report_date).to eq '2019-03-31'
18
- expect(income.total_revenue).to eq 30_505_000_000
19
- expect(income.total_revenue_dollar).to eq '$30,505,000,000'
20
- expect(income.cost_of_revenue).to eq 10_170_000_000
21
- expect(income.cost_of_revenue_dollar).to eq '$10,170,000,000'
22
- expect(income.gross_profit).to eq 20_335_000_000
23
- expect(income.gross_profit_dollar).to eq '$20,335,000,000'
24
- expect(income.research_and_development).to eq 4_316_000_000
25
- expect(income.research_and_development_dollar).to eq '$4,316,000,000'
26
- expect(income.selling_general_and_admin).to eq 5_744_000_000
27
- expect(income.selling_general_and_admin_dollar).to eq '$5,744,000,000'
28
- expect(income.operating_expense).to eq 20_230_000_000
29
- expect(income.operating_expense_dollar).to eq '$20,230,000,000'
30
- expect(income.operating_income).to eq 10_275_000_000
31
- expect(income.operating_income_dollar).to eq '$10,275,000,000'
32
- expect(income.other_income_expense_net).to eq 211_000_000
33
- expect(income.other_income_expense_net_dollar).to eq '$211,000,000'
34
- expect(income.ebit_dollar).to eq '$10,275,000,000'
35
- expect(income.ebit).to eq 10_275_000_000
36
- expect(income.interest_income).to eq 671_000_000
37
- expect(income.interest_income_dollar).to eq '$671,000,000'
38
- expect(income.pretax_income).to eq 10_486_000_000
39
- expect(income.pretax_income_dollar).to eq '$10,486,000,000'
40
- expect(income.income_tax).to eq 1_677_000_000
41
- expect(income.income_tax_dollar).to eq '$1,677,000,000'
17
+ expect(income.report_date).to eq '2020-09-30'
18
+ expect(income.fiscal_date).to eq '2020-09-30'
19
+ expect(income.currency).to eq 'USD'
20
+ expect(income.total_revenue).to eq 37_154_000_000
21
+ expect(income.total_revenue_dollar).to eq '$37,154,000,000'
22
+ expect(income.cost_of_revenue).to eq 11_002_000_000
23
+ expect(income.cost_of_revenue_dollar).to eq '$11,002,000,000'
24
+ expect(income.gross_profit).to eq 26_152_000_000
25
+ expect(income.gross_profit_dollar).to eq '$26,152,000,000'
26
+ expect(income.research_and_development).to eq 4_926_000_000
27
+ expect(income.research_and_development_dollar).to eq '$4,926,000,000'
28
+ expect(income.selling_general_and_admin).to eq 5_350_000_000
29
+ expect(income.selling_general_and_admin_dollar).to eq '$5,350,000,000'
30
+ expect(income.operating_expense).to eq 21_278_000_000
31
+ expect(income.operating_expense_dollar).to eq '$21,278,000,000'
32
+ expect(income.operating_income).to eq 15_876_000_000
33
+ expect(income.operating_income_dollar).to eq '$15,876,000,000'
34
+ expect(income.other_income_expense_net).to eq 248_000_000
35
+ expect(income.other_income_expense_net_dollar).to eq '$248,000,000'
36
+ expect(income.ebit).to eq 15_876_000_000
37
+ expect(income.ebit_dollar).to eq '$15,876,000,000'
38
+ expect(income.interest_income).to eq 589_000_000
39
+ expect(income.interest_income_dollar).to eq '$589,000,000'
40
+ expect(income.pretax_income).to eq 16_124_000_000
41
+ expect(income.pretax_income_dollar).to eq '$16,124,000,000'
42
+ expect(income.income_tax).to eq 2_231_000_000
43
+ expect(income.income_tax_dollar).to eq '$2,231,000,000'
42
44
  expect(income.minority_interest).to eq 0
43
- expect(income.net_income).to eq 8_809_000_000
44
- expect(income.net_income_dollar).to eq '$8,809,000,000'
45
- expect(income.net_income_basic).to eq 8_809_000_000
46
- expect(income.net_income_basic_dollar).to eq '$8,809,000,000'
45
+ expect(income.net_income).to eq 13_893_000_000
46
+ expect(income.net_income_dollar).to eq '$13,893,000,000'
47
+ expect(income.net_income_basic).to eq 13_893_000_000
48
+ expect(income.net_income_basic_dollar).to eq '$13,893,000,000'
47
49
  end
48
50
  end
49
51
  end
@@ -19,6 +19,7 @@ describe IEX::Resources::KeyStats do
19
19
  expect(subject.week_52_high_dollar).to eq '$136.04'
20
20
  expect(subject.week_52_low).to eq 95.92
21
21
  expect(subject.week_52_low_dollar).to eq '$95.92'
22
+ expect(subject.week_52_change).to eq 0.371641
22
23
  expect(subject.week_52_change_dollar).to eq '$0.37'
23
24
  end
24
25
 
@@ -14,6 +14,9 @@ describe IEX::Resources::News do
14
14
  expect(news.datetime.to_f).to eq 1_554_412_248.0
15
15
  expect(news.headline).to eq "Spotify joins Microsoft's Xbox Game Bar"
16
16
  expect(news.related).to eq(['MSFT'])
17
+ expect(news.image).to eq('https://cloud.iexapis.com/beta/news/image/b8a6ae18-ab19-42e8-b066-d9a9dc111f1f')
18
+ expect(news.paywalled).to eq(false)
19
+ expect(news.language).to eq('en')
17
20
  end
18
21
  end
19
22
  context 'with range', vcr: { cassette_name: 'news/msft_7' } do
@@ -18,6 +18,8 @@ describe IEX::Resources::Quote do
18
18
  expect(subject.week_52_low).to eq 87.73
19
19
  expect(subject.change_percent).to eq(-0.00508)
20
20
  expect(subject.change_percent_s).to eq '-0.51%'
21
+ expect(subject.extended_change_percent).to eq(-0.00008)
22
+ expect(subject.extended_change_percent_s).to eq '-0.01%'
21
23
  end
22
24
  it 'coerces times' do
23
25
  expect(subject.latest_update).to eq 1_554_408_000_193
@@ -3,14 +3,109 @@ require 'spec_helper'
3
3
  describe IEX::Api::Client do
4
4
  include_context 'client'
5
5
 
6
- describe 'ISIN Mapping', vcr: { cassette_name: 'ref-data/isin' } do
7
- subject do
8
- client.post('ref-data/isin', isin: ['US0378331005'], token: client.secret_token)
9
- end
10
- it 'retrieves a ticker by ISIN' do
11
- expect(subject.count).to eq(2)
12
- expect(subject.first).to eq('exchange' => 'NAS', 'iexId' => 'IEX_4D48333344362D52', 'region' => 'US', 'symbol' => 'AAPL')
13
- expect(subject.last).to eq('exchange' => 'ETR', 'iexId' => 'IEX_464D46474C312D52', 'region' => 'DE', 'symbol' => 'APC-GY')
6
+ describe '#ref_data_isin', vcr: { cassette_name: 'ref-data/isin' } do
7
+ context 'without options' do
8
+ subject { client.ref_data_isin(['US0378331005']) }
9
+
10
+ it 'converts ISIN to IEX Cloud symbols' do
11
+ expect(subject.count).to eq(2)
12
+ expect(subject.first).to eq('exchange' => 'NAS', 'iex_id' => 'IEX_4D48333344362D52', 'region' => 'US',
13
+ 'symbol' => 'AAPL')
14
+ expect(subject.last).to eq('exchange' => 'ETR', 'iex_id' => 'IEX_464D46474C312D52', 'region' => 'DE',
15
+ 'symbol' => 'APC-GY')
16
+ end
17
+ end
18
+
19
+ context 'graciously handle parameter as string', vcr: { cassette_name: 'ref-data/isin' } do
20
+ subject { client.ref_data_isin('US0378331005') }
21
+
22
+ it 'converts ISIN to IEX Cloud symbols' do
23
+ expect(subject.count).to eq(2)
24
+ expect(subject.first).to eq('exchange' => 'NAS', 'iex_id' => 'IEX_4D48333344362D52', 'region' => 'US',
25
+ 'symbol' => 'AAPL')
26
+ expect(subject.last).to eq('exchange' => 'ETR', 'iex_id' => 'IEX_464D46474C312D52', 'region' => 'DE',
27
+ 'symbol' => 'APC-GY')
28
+ end
29
+ end
30
+
31
+ context 'with mapped option', vcr: { cassette_name: 'ref-data/isin_mapped' } do
32
+ subject { client.ref_data_isin(%w[US0378331005 US5949181045], mapped: true) }
33
+
34
+ it 'converts ISINs to IEX Cloud symbols mapped by ISIN' do
35
+ expect(subject.keys).to contain_exactly('US0378331005', 'US5949181045')
36
+
37
+ expect(subject['US0378331005'].first).to eq('exchange' => 'NAS', 'iex_id' => 'IEX_4D48333344362D52',
38
+ 'region' => 'US', 'symbol' => 'AAPL')
39
+ expect(subject['US0378331005'].last).to eq('exchange' => 'ETR', 'iex_id' => 'IEX_464D46474C312D52',
40
+ 'region' => 'DE', 'symbol' => 'APC-GY')
41
+
42
+ expect(subject['US5949181045'][0]).to eq('exchange' => 'NAS', 'iex_id' => 'IEX_5038523343322D52',
43
+ 'region' => 'US', 'symbol' => 'MSFT')
44
+ expect(subject['US5949181045'][1]).to eq('exchange' => 'ETR', 'iex_id' => 'IEX_4C42583859482D52',
45
+ 'region' => 'DE', 'symbol' => 'MSF-GY')
46
+ expect(subject['US5949181045'][2]).to eq('exchange' => 'BRU', 'iex_id' => 'IEX_5833345950432D52',
47
+ 'region' => 'BE', 'symbol' => 'MSF-BB')
48
+ end
49
+ end
50
+
51
+ context 'with wrong ISIN', vcr: { cassette_name: 'ref-data/wrong_isin_mapped' } do
52
+ subject { client.ref_data_isin(%w[WRONG12345], mapped: true) }
53
+
54
+ it 'returns nil value for given ISIN' do
55
+ expect(subject).to eq('WRONG12345' => nil)
56
+ end
57
+ end
58
+ end
59
+
60
+ describe '#ref_data_symbols', vcr: { cassette_name: 'ref-data/symbols' } do
61
+ subject { client.ref_data_symbols }
62
+
63
+ it 'retrieves all symbols' do
64
+ expect(subject.count).to eq 8808
65
+ end
66
+
67
+ context 'first symbol' do
68
+ subject { client.ref_data_symbols.first }
69
+ it 'retrieves a symbol data' do
70
+ expect(subject.symbol).to eq 'A'
71
+ expect(subject.exchange).to eq 'NYS'
72
+ expect(subject.name).to eq 'Agilent Technologies Inc.'
73
+ expect(subject.date).to eq Date.parse('2020-04-30')
74
+ expect(subject.enabled).to eq true
75
+ expect(subject.enabled?).to eq true
76
+ expect(subject.type).to eq 'cs'
77
+ expect(subject.region).to eq 'US'
78
+ expect(subject.currency).to eq 'USD'
79
+ expect(subject.iex_id).to eq 'IEX_46574843354B2D52'
80
+ expect(subject.figi).to eq 'BBG000C2V3D6'
81
+ expect(subject.cik).to eq '1090872'
82
+ end
83
+ end
84
+ end
85
+
86
+ describe '#ref_data_symbols_for_exchange', vcr: { cassette_name: 'ref-data/exchange_symbols' } do
87
+ subject { client.ref_data_symbols_for_exchange('TSX') }
88
+
89
+ it 'retrieves all symbols' do
90
+ expect(subject.count).to eq 1869
91
+ end
92
+
93
+ context 'first symbol' do
94
+ subject { client.ref_data_symbols_for_exchange('TSX').first }
95
+ it 'retrieves a symbol data' do
96
+ expect(subject.symbol).to eq 'A-CV'
97
+ expect(subject.exchange).to eq 'TSX'
98
+ expect(subject.name).to eq 'Armor Minerals Inc'
99
+ expect(subject.date).to eq Date.parse('2021-05-14')
100
+ expect(subject.enabled).to eq true
101
+ expect(subject.enabled?).to eq true
102
+ expect(subject.type).to eq 'cs'
103
+ expect(subject.region).to eq 'CA'
104
+ expect(subject.currency).to eq 'CAD'
105
+ expect(subject.iex_id).to eq 'IEX_4656374258322D52'
106
+ expect(subject.figi).to eq 'BBG000V98LH2'
107
+ expect(subject.cik).to eq '0001682145'
108
+ end
14
109
  end
15
110
  end
16
111
  end