tradier 0.1.0

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 (119) hide show
  1. data/.yardopts +8 -0
  2. data/LICENSE.md +20 -0
  3. data/README.md +114 -0
  4. data/Rakefile +19 -0
  5. data/lib/tradier.rb +31 -0
  6. data/lib/tradier/account.rb +30 -0
  7. data/lib/tradier/api/accounts.rb +122 -0
  8. data/lib/tradier/api/markets.rb +113 -0
  9. data/lib/tradier/api/orders.rb +84 -0
  10. data/lib/tradier/api/utils.rb +47 -0
  11. data/lib/tradier/api/utils/account.rb +15 -0
  12. data/lib/tradier/api/utils/balance.rb +15 -0
  13. data/lib/tradier/api/utils/base.rb +46 -0
  14. data/lib/tradier/api/utils/event.rb +15 -0
  15. data/lib/tradier/api/utils/expiration.rb +19 -0
  16. data/lib/tradier/api/utils/gainloss.rb +15 -0
  17. data/lib/tradier/api/utils/history.rb +15 -0
  18. data/lib/tradier/api/utils/option_quote.rb +15 -0
  19. data/lib/tradier/api/utils/order.rb +15 -0
  20. data/lib/tradier/api/utils/position.rb +15 -0
  21. data/lib/tradier/api/utils/quote.rb +15 -0
  22. data/lib/tradier/api/utils/strike.rb +15 -0
  23. data/lib/tradier/api/utils/timesales.rb +15 -0
  24. data/lib/tradier/api/utils/watchlist.rb +15 -0
  25. data/lib/tradier/api/watchlists.rb +139 -0
  26. data/lib/tradier/balance.rb +17 -0
  27. data/lib/tradier/base.rb +76 -0
  28. data/lib/tradier/calendar.rb +23 -0
  29. data/lib/tradier/client.rb +89 -0
  30. data/lib/tradier/clock.rb +21 -0
  31. data/lib/tradier/configurable.rb +76 -0
  32. data/lib/tradier/core_ext/enumerable.rb +9 -0
  33. data/lib/tradier/default.rb +75 -0
  34. data/lib/tradier/error.rb +34 -0
  35. data/lib/tradier/error/bad_gateway.rb +11 -0
  36. data/lib/tradier/error/bad_request.rb +10 -0
  37. data/lib/tradier/error/client_error.rb +28 -0
  38. data/lib/tradier/error/configuration_error.rb +6 -0
  39. data/lib/tradier/error/decode_error.rb +9 -0
  40. data/lib/tradier/error/forbidden.rb +10 -0
  41. data/lib/tradier/error/gateway_timeout.rb +11 -0
  42. data/lib/tradier/error/internal_server_error.rb +11 -0
  43. data/lib/tradier/error/not_acceptable.rb +10 -0
  44. data/lib/tradier/error/not_found.rb +10 -0
  45. data/lib/tradier/error/raise_error.rb +31 -0
  46. data/lib/tradier/error/server_error.rb +28 -0
  47. data/lib/tradier/error/service_unavailable.rb +11 -0
  48. data/lib/tradier/error/too_many_requests.rb +12 -0
  49. data/lib/tradier/error/unauthorized.rb +10 -0
  50. data/lib/tradier/error/unprocessable_entity.rb +10 -0
  51. data/lib/tradier/event.rb +8 -0
  52. data/lib/tradier/history.rb +20 -0
  53. data/lib/tradier/option_quote.rb +37 -0
  54. data/lib/tradier/order.rb +14 -0
  55. data/lib/tradier/position.rb +7 -0
  56. data/lib/tradier/profile.rb +14 -0
  57. data/lib/tradier/quote.rb +12 -0
  58. data/lib/tradier/response/parse_json.rb +25 -0
  59. data/lib/tradier/response/raise_error.rb +31 -0
  60. data/lib/tradier/symbol.rb +147 -0
  61. data/lib/tradier/timesales.rb +11 -0
  62. data/lib/tradier/version.rb +3 -0
  63. data/lib/tradier/watchlist.rb +16 -0
  64. data/lib/tradier/watchlist_item.rb +17 -0
  65. data/spec/fixtures/account_balances.json +28 -0
  66. data/spec/fixtures/account_gainloss.json +18 -0
  67. data/spec/fixtures/account_history.json +96 -0
  68. data/spec/fixtures/account_orders.json +833 -0
  69. data/spec/fixtures/account_positions.json +22 -0
  70. data/spec/fixtures/calendar.json +400 -0
  71. data/spec/fixtures/chain.json +2972 -0
  72. data/spec/fixtures/clock.json +10 -0
  73. data/spec/fixtures/expirations.json +18 -0
  74. data/spec/fixtures/history.json +2086 -0
  75. data/spec/fixtures/option_quote.json +14 -0
  76. data/spec/fixtures/option_quotes.json +26 -0
  77. data/spec/fixtures/order.json +1 -0
  78. data/spec/fixtures/order_with_warnings.json +17 -0
  79. data/spec/fixtures/placed_order.json +6 -0
  80. data/spec/fixtures/quote.json +45 -0
  81. data/spec/fixtures/quotes.json +88 -0
  82. data/spec/fixtures/session.json +6 -0
  83. data/spec/fixtures/strikes.json +173 -0
  84. data/spec/fixtures/timesales.json +2956 -0
  85. data/spec/fixtures/user_balances.json +118 -0
  86. data/spec/fixtures/user_gainloss.json +6775 -0
  87. data/spec/fixtures/user_history.json +101 -0
  88. data/spec/fixtures/user_orders.json +57 -0
  89. data/spec/fixtures/user_positions.json +50 -0
  90. data/spec/fixtures/user_profile.json +103 -0
  91. data/spec/fixtures/watchlist.json +30 -0
  92. data/spec/fixtures/watchlist_item.json +6 -0
  93. data/spec/fixtures/watchlists.json +18 -0
  94. data/spec/spec_helper.rb +64 -0
  95. data/spec/tradier/account_spec.rb +76 -0
  96. data/spec/tradier/api/accounts_spec.rb +195 -0
  97. data/spec/tradier/api/markets_spec.rb +219 -0
  98. data/spec/tradier/api/orders_spec.rb +94 -0
  99. data/spec/tradier/api/utils/expiration_spec.rb +8 -0
  100. data/spec/tradier/api/watchlists_spec.rb +164 -0
  101. data/spec/tradier/balance_spec.rb +4 -0
  102. data/spec/tradier/base_spec.rb +11 -0
  103. data/spec/tradier/calendar_spec.rb +27 -0
  104. data/spec/tradier/client_spec.rb +125 -0
  105. data/spec/tradier/clock_spec.rb +73 -0
  106. data/spec/tradier/error/client_error_spec.rb +22 -0
  107. data/spec/tradier/error/server_error_spec.rb +22 -0
  108. data/spec/tradier/error_spec.rb +26 -0
  109. data/spec/tradier/option_quote_spec.rb +61 -0
  110. data/spec/tradier/order_spec.rb +43 -0
  111. data/spec/tradier/position_spec.rb +4 -0
  112. data/spec/tradier/profile_spec.rb +28 -0
  113. data/spec/tradier/quote_spec.rb +29 -0
  114. data/spec/tradier/symbol_spec.rb +54 -0
  115. data/spec/tradier/watchlist_item_spec.rb +48 -0
  116. data/spec/tradier/watchlist_spec.rb +35 -0
  117. data/spec/tradier_spec.rb +105 -0
  118. data/tradier.gemspec +30 -0
  119. metadata +302 -0
@@ -0,0 +1,26 @@
1
+ require 'spec_helper'
2
+
3
+ describe Tradier::Error do
4
+
5
+ describe "#initialize" do
6
+ it "wraps another error class" do
7
+ begin
8
+ raise Faraday::Error::ClientError.new("Oops")
9
+ rescue Faraday::Error::ClientError
10
+ begin
11
+ raise Tradier::Error
12
+ rescue Tradier::Error => error
13
+ expect(error.message).to eq "Oops"
14
+ expect(error.wrapped_exception.class).to eq Faraday::Error::ClientError
15
+ end
16
+ end
17
+ end
18
+ end
19
+
20
+ describe "#errors" do
21
+ it "lists descendant errors" do
22
+ expect(Tradier::Error.errors).to have_key(403)
23
+ end
24
+ end
25
+
26
+ end
@@ -0,0 +1,61 @@
1
+ require 'spec_helper'
2
+
3
+ describe Tradier::OptionQuote do
4
+
5
+ describe "#==" do
6
+ it "returns true when objects symbols are the same" do
7
+ quote = Tradier::OptionQuote.new(:symbol => 'AAPL150117C01000000')
8
+ other = Tradier::OptionQuote.new(:symbol => 'AAPL150117C01000000')
9
+ expect(quote == other).to be_true
10
+ end
11
+ it "returns false when objects IDs are different" do
12
+ quote = Tradier::OptionQuote.new(:symbol => 'AAPL150117C01000000')
13
+ other = Tradier::OptionQuote.new(:symbol => 'AAPL150117P01000000')
14
+ expect(quote == other).to be_false
15
+ end
16
+ end
17
+
18
+ describe '#put?' do
19
+ it 'returns true when the option is a put' do
20
+ quote = Tradier::OptionQuote.new(:symbol => 'AAPL150117P01000000')
21
+ expect(quote.put?).to be_true
22
+ end
23
+
24
+ it 'returns false when the option is a call' do
25
+ quote = Tradier::OptionQuote.new(:symbol => 'AAPL150117C01000000')
26
+ expect(quote.put?).to be_false
27
+ end
28
+ end
29
+
30
+ describe '#call?' do
31
+ it 'returns true when the option is a call' do
32
+ quote = Tradier::OptionQuote.new(:symbol => 'AAPL150117C01000000')
33
+ expect(quote.call?).to be_true
34
+ end
35
+
36
+ it 'returns false when the option is a call' do
37
+ quote = Tradier::OptionQuote.new(:symbol => 'AAPL150117P01000000')
38
+ expect(quote.call?).to be_false
39
+ end
40
+ end
41
+
42
+ describe '#expiration_date' do
43
+ it "returns the expiration_date when set" do
44
+ quote = Tradier::OptionQuote.new(:expiration_date => '2013-07-04')
45
+ expect(quote.expiration_date).to be_a Date
46
+ expect(quote.expiration_date.to_s).to eq('2013-07-04')
47
+ end
48
+ it "returns nil when expirationdate is not set" do
49
+ quote = Tradier::OptionQuote.new(:symbol => 'AAPL150117P01000000')
50
+ expect(quote.expiration_date).to be_nil
51
+ end
52
+ end
53
+
54
+ describe '#underlier' do
55
+ it 'returns the underlying symbol for the option' do
56
+ quote = Tradier::OptionQuote.new(:symbol => 'AAPL150117C01000000')
57
+ expect(quote.underlier).to eq('AAPL')
58
+ end
59
+ end
60
+
61
+ end
@@ -0,0 +1,43 @@
1
+ require 'spec_helper'
2
+
3
+ describe Tradier::Order do
4
+ describe '.from_response' do
5
+ context 'new order' do
6
+ let(:response) { MultiJson.decode(fixture('placed_order.json'), :symbolize_keys => true) }
7
+ let(:order) { Tradier::Order.from_response(response) }
8
+
9
+ it 'populates the order id' do
10
+ expect(order.id).to eq(2038)
11
+ end
12
+
13
+ it 'populates the order status' do
14
+ expect(order.status).to eq('OK')
15
+ end
16
+ end
17
+
18
+ context 'previewed order' do
19
+ let(:response) { MultiJson.decode(fixture('order_with_warnings.json'), :symbolize_keys => true) }
20
+ let(:order) { Tradier::Order.from_response(response) }
21
+
22
+ it 'populates the order side' do
23
+ expect(order.side).to eq('Buy')
24
+ end
25
+
26
+ it 'populates the order status' do
27
+ expect(order.status).to eq('Bad Request')
28
+ end
29
+
30
+ it 'populates the order symbol' do
31
+ expect(order.symbol).to eq('AAPL')
32
+ end
33
+
34
+ it 'populates the order time_in_force' do
35
+ expect(order.time_in_force).to eq('Day')
36
+ end
37
+
38
+ it 'populates the order type' do
39
+ expect(order.type).to eq('Market')
40
+ end
41
+ end
42
+ end
43
+ end
@@ -0,0 +1,4 @@
1
+ require 'spec_helper'
2
+
3
+ describe Tradier::Position do
4
+ end
@@ -0,0 +1,28 @@
1
+ require 'spec_helper'
2
+
3
+ describe Tradier::Profile do
4
+
5
+ describe "#name" do
6
+ it "returns the name when set" do
7
+ profile = Tradier::Profile.new(:profile => { :name => 'Elaine Benes'})
8
+ expect(profile.name).to eq('Elaine Benes')
9
+ end
10
+ it "returns nil when name is not set" do
11
+ profile = Tradier::Profile.new({})
12
+ expect(profile.name).to be_nil
13
+ end
14
+ end
15
+
16
+ describe '#accounts' do
17
+ it "returns the accounts when set" do
18
+ profile = Tradier::Profile.new(:profile => { :account => [{:account_number => '123456789', :type => 'Cash'}] })
19
+ expect(profile.accounts).to be_an Array
20
+ expect(profile.accounts.first).to be_a Tradier::Account
21
+ end
22
+ it "returns nil when accounts is not set" do
23
+ profile = Tradier::Profile.new({})
24
+ expect(profile.accounts).to be_nil
25
+ end
26
+ end
27
+
28
+ end
@@ -0,0 +1,29 @@
1
+ require 'spec_helper'
2
+
3
+ describe Tradier::Quote do
4
+
5
+ describe "#==" do
6
+ it "returns true when objects symbols are the same" do
7
+ quote = Tradier::Quote.new({ :symbol => 'AAPL' })
8
+ other = Tradier::Quote.new({ :symbol => 'AAPL' })
9
+ expect(quote == other).to be_true
10
+ end
11
+ it "returns false when objects IDs are different" do
12
+ quote = Tradier::Quote.new({ :symbol => 'AAPL' })
13
+ other = Tradier::Quote.new({ :symbol => 'GE' })
14
+ expect(quote == other).to be_false
15
+ end
16
+ end
17
+
18
+ describe "#symbol" do
19
+ it "returns the symbol when set" do
20
+ quote = Tradier::Quote.new({ :symbol => 'AAPL' })
21
+ expect(quote.symbol).to eq('AAPL')
22
+ end
23
+ it "returns nil when symbol is not set" do
24
+ quote = Tradier::Quote.new('Quote' => {})
25
+ expect(quote.symbol).to be_nil
26
+ end
27
+ end
28
+
29
+ end
@@ -0,0 +1,54 @@
1
+ require 'spec_helper'
2
+
3
+ describe Tradier::Symbol do
4
+
5
+ describe '.parse' do
6
+ it 'raises an expection when passed a numeric string' do
7
+ expect { Tradier::Symbol.parse('123') }.to raise_error(ArgumentError)
8
+ end
9
+
10
+ it 'raises an expection when passed an unparseable' do
11
+ expect { Tradier::Symbol.parse('#%$@###') }.to raise_error(ArgumentError)
12
+ end
13
+
14
+ it 'allows a root symbol to be parsed' do
15
+ symbol = Tradier::Symbol.parse('AAPL')
16
+ expect(symbol).to be_valid
17
+ end
18
+ end
19
+
20
+ describe '#description' do
21
+ it 'returns the text description of an option' do
22
+ symbol = Tradier::Symbol.parse('AAPL130622C00280000')
23
+ expect(symbol.description).to eq('AAPL Jun 22 2013 $280.00 CALL')
24
+ end
25
+ end
26
+
27
+ describe '#expiration' do
28
+ it 'returns a Date object' do
29
+ symbol = Tradier::Symbol.parse('AAPL130622C00280000')
30
+ expect(symbol.expiration).to be_a(Date)
31
+ end
32
+ end
33
+
34
+ describe '#strike_price' do
35
+ it 'returns the strike price as a Fixnum' do
36
+ symbol = Tradier::Symbol.parse('AAPL130622C00280000')
37
+ expect(symbol.strike_price).to eq(280.00)
38
+ end
39
+ end
40
+
41
+ describe '#to_s' do
42
+ it 'returns the original symbol' do
43
+ symbol = Tradier::Symbol.parse('AAPL130622C00280000')
44
+ expect(symbol.to_s).to eq('AAPL130622C00280000')
45
+ end
46
+ end
47
+
48
+ describe '#underlier' do
49
+ it 'returns the root symbol' do
50
+ symbol = Tradier::Symbol.parse('AAPL130622C00280000')
51
+ expect(symbol.underlier).to eq('AAPL')
52
+ end
53
+ end
54
+ end
@@ -0,0 +1,48 @@
1
+ require 'spec_helper'
2
+
3
+ describe Tradier::WatchlistItem do
4
+ describe '#symbol' do
5
+ it "returns the symbol when set" do
6
+ item = Tradier::WatchlistItem.new({ :symbol => 'AAPL' })
7
+ expect(item.symbol).to eq('AAPL')
8
+ end
9
+ it "returns nil when symbol is not set" do
10
+ item = Tradier::WatchlistItem.new({ :price => 1.00 })
11
+ expect(item.symbol).to be_nil
12
+ end
13
+ end
14
+
15
+ describe '#shares' do
16
+ it "returns the shares when set" do
17
+ item = Tradier::WatchlistItem.new({ :shares => 100 })
18
+ expect(item.shares).to eq(100)
19
+ end
20
+ it "returns nil when shares is not set" do
21
+ item = Tradier::WatchlistItem.new({ :symbol => 'AAPL' })
22
+ expect(item.shares).to be_nil
23
+ end
24
+ end
25
+
26
+ describe '#purchase_price' do
27
+ it "returns the purchase_price when set" do
28
+ item = Tradier::WatchlistItem.new({ :purchase_price => 100 })
29
+ expect(item.purchase_price).to eq(100)
30
+ end
31
+ it "returns nil when purchase_price is not set" do
32
+ item = Tradier::WatchlistItem.new({ :symbol => 'AAPL' })
33
+ expect(item.purchase_price).to be_nil
34
+ end
35
+ end
36
+
37
+ describe "#purchase_date" do
38
+ it "returns the purchase_date when set" do
39
+ clock = Tradier::WatchlistItem.new({ :purchase_date => '2013-07-04' })
40
+ expect(clock.purchase_date).to be_a Date
41
+ expect(clock.purchase_date.to_s).to eq('2013-07-04')
42
+ end
43
+ it "returns nil when purchase_date is not set" do
44
+ clock = Tradier::WatchlistItem.new({ :symbol => 'AAPL' })
45
+ expect(clock.purchase_date).to be_nil
46
+ end
47
+ end
48
+ end
@@ -0,0 +1,35 @@
1
+ require 'spec_helper'
2
+
3
+ describe Tradier::Watchlist do
4
+ describe '#id' do
5
+ it "returns the id when set" do
6
+ watchlist = Tradier::Watchlist.new({ :id => 'default' })
7
+ expect(watchlist.id).to eq('default')
8
+ end
9
+ it "returns nil when id is not set" do
10
+ watchlist = Tradier::Watchlist.new({ :name => 'Default' })
11
+ expect(watchlist.id).to be_nil
12
+ end
13
+ end
14
+
15
+ describe '#name' do
16
+ it "returns the name when set" do
17
+ watchlist = Tradier::Watchlist.new({ :name => 'Default' })
18
+ expect(watchlist.name).to eq('Default')
19
+ end
20
+ it "returns nil when name is not set" do
21
+ watchlist = Tradier::Watchlist.new({ :id => 'default' })
22
+ expect(watchlist.name).to be_nil
23
+ end
24
+ end
25
+
26
+ describe '#items' do
27
+ it "returns an array of watchlist items" do
28
+ response = {:items => { :item => [{:symbol => 'AAPL'}, { :symbol => 'GE'}]}}
29
+ watchlist = Tradier::Watchlist.new(response)
30
+ expect(watchlist.items).to be_an Array
31
+ expect(watchlist.items.size).to eq(2)
32
+ expect(watchlist.items.first).to be_a Tradier::WatchlistItem
33
+ end
34
+ end
35
+ end
@@ -0,0 +1,105 @@
1
+ require 'spec_helper'
2
+
3
+ describe Tradier do
4
+
5
+ after do
6
+ Tradier.reset!
7
+ end
8
+
9
+ context "when delegating to a client" do
10
+
11
+ before do
12
+ stub_get("/v1/markets/quotes").
13
+ with(:query => {:symbols => "AAPL"}).
14
+ to_return(:body => fixture("quote.json"), :headers => {:content_type => "application/json; charset=utf-8"})
15
+ end
16
+
17
+ it "requests the correct resource" do
18
+ Tradier.quotes('AAPL')
19
+ expect(a_get("/v1/markets/quotes").with(:query => {:symbols => "AAPL"})).to have_been_made
20
+ end
21
+
22
+ it "returns the same results as a client" do
23
+ expect(Tradier.quotes('AAPL')).to eq Tradier::Client.new.quotes('AAPL')
24
+ end
25
+
26
+ end
27
+
28
+ describe ".respond_to?" do
29
+ it "delegates to Tradier::Client" do
30
+ expect(Tradier.respond_to?(:quotes)).to be_true
31
+ end
32
+ it "takes an optional argument" do
33
+ expect(Tradier.respond_to?(:quotes, true)).to be_true
34
+ end
35
+ end
36
+
37
+ describe ".client" do
38
+ it "returns a Tradier::Client" do
39
+ expect(Tradier.client).to be_a Tradier::Client
40
+ end
41
+
42
+ context "when the options don't change" do
43
+ it "caches the client" do
44
+ expect(Tradier.client).to eq Tradier.client
45
+ end
46
+ end
47
+ context "when the options change" do
48
+ it "busts the cache" do
49
+ client1 = Tradier.client
50
+ Tradier.configure do |config|
51
+ config.access_token = 'abc'
52
+ end
53
+ client2 = Tradier.client
54
+ expect(client1).not_to eq client2
55
+ end
56
+ end
57
+ end
58
+
59
+ describe ".configure" do
60
+ Tradier::Configurable.keys.each do |key|
61
+ it "sets the #{key.to_s.gsub('_', ' ')}" do
62
+ Tradier.configure do |config|
63
+ config.send("#{key}=", key)
64
+ end
65
+ expect(Tradier.instance_variable_get(:"@#{key}")).to eq key
66
+ end
67
+ end
68
+
69
+ context "when invalid credentials are provided" do
70
+ it "raises a ConfigurationError exception" do
71
+ expect {
72
+ Tradier.configure do |config|
73
+ config.access_token = [12345, 54321]
74
+ end
75
+ }.to raise_error
76
+ end
77
+ end
78
+
79
+ context "when no credentials are provided" do
80
+ it "does not raise an exception" do
81
+ expect {
82
+ Tradier.configure do |config|
83
+ config.access_token = nil
84
+ end
85
+ }.to_not raise_error
86
+ end
87
+ end
88
+ end
89
+
90
+ describe ".credentials?" do
91
+ it "returns true if all oauth credentials are present" do
92
+ Tradier.configure do |config|
93
+ config.access_token = 'OT'
94
+ end
95
+ expect(Tradier.credentials?).to be_true
96
+ end
97
+ it "returns false if any credentials are missing" do
98
+ Tradier.configure do |config|
99
+ config.version = 'v2'
100
+ end
101
+ expect(Tradier.credentials?).to be_false
102
+ end
103
+ end
104
+
105
+ end
@@ -0,0 +1,30 @@
1
+ # coding: utf-8
2
+ lib = File.expand_path('../lib', __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+ require 'tradier/version'
5
+
6
+ Gem::Specification.new do |gem|
7
+ gem.name = 'tradier'
8
+ gem.version = Tradier::VERSION
9
+ gem.homepage = 'https://github.com/tradier/tradier.rb'
10
+
11
+ gem.author = ["Steve Agalloco", "Jason Barry"]
12
+ gem.email = ['steve.agalloco@gmail.com', 'jay@jcbarry.com']
13
+ gem.description = "Rubygem for interacting with the Tradier API."
14
+ gem.summary = gem.description
15
+
16
+ gem.license = 'MIT'
17
+
18
+ gem.add_dependency 'faraday', ['~> 0.8', '< 0.10']
19
+ gem.add_dependency 'faraday_middleware', ['~> 0.8', '< 0.10']
20
+ gem.add_dependency 'celluloid'
21
+ gem.add_development_dependency 'bundler', '~> 1'
22
+
23
+ gem.files = %w(.yardopts LICENSE.md README.md Rakefile tradier.gemspec)
24
+ gem.files += Dir.glob("lib/**/*.rb")
25
+ gem.files += Dir.glob("spec/**/*")
26
+
27
+ gem.test_files = Dir.glob("spec/**/*")
28
+
29
+ gem.require_paths = ['lib']
30
+ end