bitstampede 0.1.5 → 0.1.6

Sign up to get free protection for your applications and to get access to all the features.
data/README.md CHANGED
@@ -37,6 +37,9 @@ client = Bitstampede::Client.new
37
37
  client.key = 'YOUR_USER_ID'
38
38
  client.secret = 'YOUR_PASSWORD'
39
39
 
40
+ # Alternatively, you can configure the client on initialization with:
41
+ client = Bitstampede::Client.new('YOUR_USER_ID', 'YOUR_PASSWORD')
42
+
40
43
  # Fetch your balance
41
44
  client.balance
42
45
  # => #<Bitstampede::Entities::Balance:0x0000000259f338 @usd_balance=#<BigDecimal:259e898,'0.0',9(9)>, @btc_balance=#<BigDecimal:2726698,'0.0',9(9)>, @usd_reserved=#<BigDecimal:2726328,'0.0',9(9)>, @btc_reserved=#<BigDecimal:2725fb8,'0.0',9(9)>, @usd_available=#<BigDecimal:2725c48,'0.0',9(9)>, @btc_available=#<BigDecimal:27258b0,'0.0',9(9)>, @fee=#<BigDecimal:2725540,'0.0',9(9)>>
@@ -75,3 +78,10 @@ ruby example/balance.rb
75
78
  ## License
76
79
 
77
80
  This software is licensed under [the MIT License.](./LICENSE.md)
81
+
82
+ ## Contributors
83
+
84
+ These people have contributed to the gem. Many thanks!:
85
+
86
+ - Josh Adams
87
+ - [Robert Jackson](https://github.com/rjackson)
@@ -7,7 +7,9 @@ module Bitstampede
7
7
  attr_accessor :key
8
8
  attr_accessor :secret
9
9
 
10
- def initialize
10
+ def initialize(key = nil, secret = nil)
11
+ @key = key
12
+ @secret = secret
11
13
  end
12
14
 
13
15
  def balance
@@ -9,10 +9,9 @@ module Bitstampede
9
9
  self.mappings.keys
10
10
  end
11
11
 
12
- def initialize(balance_hash)
13
- self.class.keys.each do |key|
14
- instance_variable_set("@#{key}", self.class.mappings[key].call(balance_hash[key.to_s].to_s))
15
- end
12
+ def initialize(hash)
13
+ check_for_errors(hash)
14
+ map_instance_variables(hash)
16
15
  end
17
16
 
18
17
  def inspect
@@ -35,6 +34,19 @@ module Bitstampede
35
34
  def self.map_decimal
36
35
  ->(val) { BigDecimal(val) }
37
36
  end
37
+
38
+ private
39
+ def map_instance_variables(hash)
40
+ self.class.keys.each do |key|
41
+ instance_variable_set("@#{key}", self.class.mappings[key].call(hash[key.to_s].to_s))
42
+ end
43
+ end
44
+
45
+ def check_for_errors(hash)
46
+ if hash.keys.include?("error")
47
+ raise Bitstampede::StandardError.new(hash["error"]["__all__"].join(". "))
48
+ end
49
+ end
38
50
  end
39
51
  end
40
52
  end
@@ -44,7 +44,7 @@ module Bitstampede
44
44
  end
45
45
 
46
46
  def raw_post(endpoint, options)
47
- HTTParty.post(url_for(endpoint), body: options.merge(auth_options)).to_s
47
+ HTTParty.post(url_for(endpoint), body: options.merge(auth_options)).to_s.tap {|r| STDOUT.puts r}
48
48
  end
49
49
  end
50
50
  end
@@ -1,3 +1,3 @@
1
1
  module Bitstampede
2
- VERSION = "0.1.5"
2
+ VERSION = "0.1.6"
3
3
  end
@@ -46,21 +46,33 @@ describe "Integrating a client" do
46
46
  expect(orders[0].type).to eq(:buy)
47
47
  end
48
48
 
49
- it "handles #buy!" do
50
- example_buy_response = <<-JSON
51
- {
52
- "id": "1",
53
- "datetime": "1234567",
54
- "type": 0,
55
- "price": "12.34",
56
- "amount": "100"
57
- }
58
- JSON
49
+ context "handling #buy!" do
50
+ it "succeeds properly" do
51
+ example_buy_response = <<-JSON
52
+ {
53
+ "id": "1",
54
+ "datetime": "1234567",
55
+ "type": 0,
56
+ "price": "12.34",
57
+ "amount": "100"
58
+ }
59
+ JSON
60
+
61
+ FakeWeb.register_uri(:post, "https://www.bitstamp.net/api/buy/", body: example_buy_response)
62
+
63
+ buy = subject.buy!(BigDecimal('1'), BigDecimal('100'))
64
+ expect(buy.type).to eq(:buy)
65
+ end
66
+
67
+ it "fails properly" do
68
+ example_buy_response = <<-JSON
69
+ {"error"=>{"__all__"=>["Minimum order size is $1"]}}
70
+ JSON
59
71
 
60
- FakeWeb.register_uri(:post, "https://www.bitstamp.net/api/buy/", body: example_buy_response)
72
+ FakeWeb.register_uri(:post, "https://www.bitstamp.net/api/buy/", body: example_buy_response)
61
73
 
62
- buy = subject.buy!(BigDecimal('1'), BigDecimal('100'))
63
- expect(buy.type).to eq(:buy)
74
+ expect{ subject.buy!(BigDecimal('1'), BigDecimal('100')) }.to raise_error(Bitstampede::StandardError, "Minimum order size is $1")
75
+ end
64
76
  end
65
77
 
66
78
  it "handles #sell!" do
@@ -1,13 +1,26 @@
1
1
  require_relative '../../spec_helper'
2
2
 
3
3
  describe Bitstampede::Client do
4
- subject { described_class.new }
5
- let(:net){ subject.send(:net) }
6
- let(:mapper){ subject.send(:mapper) }
4
+ subject(:client) { described_class.new }
5
+ let(:net){ client.send(:net) }
6
+ let(:mapper){ client.send(:mapper) }
7
7
 
8
8
  before do
9
- subject.key = '1'
10
- subject.secret = '2'
9
+ client.key = '1'
10
+ client.secret = '2'
11
+ end
12
+
13
+ describe '#initialize' do
14
+ it 'does not require any initial parameters' do
15
+ expect { described_class.new }.not_to raise_error
16
+ end
17
+
18
+ it 'allows specifying key/secret on initialize' do
19
+ client = described_class.new('KEY', 'SECRET')
20
+
21
+ expect(client.key).to eql('KEY')
22
+ expect(client.secret).to eql('SECRET')
23
+ end
11
24
  end
12
25
 
13
26
  describe '#balance' do
@@ -17,7 +30,7 @@ describe Bitstampede::Client do
17
30
  before do
18
31
  net.stub(:post).and_return(api_balance_response)
19
32
  mapper.stub(:map_balance).and_return(balance_object)
20
- subject.balance
33
+ client.balance
21
34
  end
22
35
 
23
36
  it 'requests the balance from the API' do
@@ -29,7 +42,7 @@ describe Bitstampede::Client do
29
42
  end
30
43
 
31
44
  it 'returns the mapped object' do
32
- expect(subject.balance).to eq(balance_object)
45
+ expect(client.balance).to eq(balance_object)
33
46
  end
34
47
  end
35
48
 
@@ -40,7 +53,7 @@ describe Bitstampede::Client do
40
53
  before do
41
54
  net.stub(:post).and_return(api_orders_response)
42
55
  mapper.stub(:map_orders).and_return([order_object])
43
- subject.orders
56
+ client.orders
44
57
  end
45
58
 
46
59
  it 'requests open orders from the API' do
@@ -62,18 +75,18 @@ describe Bitstampede::Client do
62
75
  end
63
76
 
64
77
  it 'submits a buy order to the API' do
65
- subject.buy!(BigDecimal('100'), BigDecimal('1'))
78
+ client.buy!(BigDecimal('100'), BigDecimal('1'))
66
79
  expect(net).to have_received(:post).with('buy', { amount: '100.0', price: '1.0' })
67
80
  end
68
81
 
69
82
  it 'maps the API response to an Order object' do
70
- subject.buy!(BigDecimal('100'), BigDecimal('1'))
83
+ client.buy!(BigDecimal('100'), BigDecimal('1'))
71
84
  expect(mapper).to have_received(:map_order).with(api_buy_response)
72
85
  end
73
86
 
74
87
  it 'wraps exceptions in its own class' do
75
88
  net.stub(:post).and_raise(StandardError)
76
- expect{ subject.buy!(BigDecimal('100'), BigDecimal('1')) }.to raise_error(Bitstampede::StandardError)
89
+ expect{ client.buy!(BigDecimal('100'), BigDecimal('1')) }.to raise_error(Bitstampede::StandardError)
77
90
  end
78
91
  end
79
92
 
@@ -84,7 +97,7 @@ describe Bitstampede::Client do
84
97
  before do
85
98
  net.stub(:post).and_return(api_sell_response)
86
99
  mapper.stub(:map_order).and_return(order_object)
87
- subject.sell!(BigDecimal('100'), BigDecimal('1'))
100
+ client.sell!(BigDecimal('100'), BigDecimal('1'))
88
101
  end
89
102
 
90
103
  it 'submits a sell order to the API' do
@@ -97,7 +110,7 @@ describe Bitstampede::Client do
97
110
 
98
111
  it 'wraps exceptions in its own class' do
99
112
  net.stub(:post).and_raise(StandardError)
100
- expect{ subject.sell!(BigDecimal('100'), BigDecimal('1')) }.to raise_error(Bitstampede::StandardError)
113
+ expect{ client.sell!(BigDecimal('100'), BigDecimal('1')) }.to raise_error(Bitstampede::StandardError)
101
114
  end
102
115
  end
103
116
 
@@ -107,7 +120,7 @@ describe Bitstampede::Client do
107
120
  before do
108
121
  net.stub(:post).and_return(api_cancel_response)
109
122
  mapper.stub(:map_cancel).and_return(true)
110
- subject.cancel(1234)
123
+ client.cancel(1234)
111
124
  end
112
125
 
113
126
  it 'submits a cancel order to the API' do
@@ -120,7 +133,7 @@ describe Bitstampede::Client do
120
133
 
121
134
  it 'wraps exceptions in its own class' do
122
135
  net.stub(:post).and_raise(StandardError)
123
- expect{ subject.cancel(123) }.to raise_error(Bitstampede::StandardError)
136
+ expect{ client.cancel(123) }.to raise_error(Bitstampede::StandardError)
124
137
  end
125
138
  end
126
139
  end
@@ -12,37 +12,37 @@ describe Bitstampede::Entities::Balance do
12
12
  "fee" => "1.11"
13
13
  }
14
14
  }
15
- subject{ described_class.new(balance_hash) }
15
+ subject(:balance) { described_class.new(balance_hash) }
16
16
 
17
17
  it "has a usd_balance" do
18
- expect(subject.usd_balance).to eq(BigDecimal('111.12'))
18
+ expect(balance.usd_balance).to eq(BigDecimal('111.12'))
19
19
  end
20
20
 
21
21
  it "has a btc_balance" do
22
- expect(subject.btc_balance).to eq(BigDecimal('211.23'))
22
+ expect(balance.btc_balance).to eq(BigDecimal('211.23'))
23
23
  end
24
24
 
25
25
  it "has a usd_reserved" do
26
- expect(subject.usd_reserved).to eq(BigDecimal('1.20'))
26
+ expect(balance.usd_reserved).to eq(BigDecimal('1.20'))
27
27
  end
28
28
 
29
29
  it "has a btc_reserved" do
30
- expect(subject.btc_reserved).to eq(BigDecimal('2.30'))
30
+ expect(balance.btc_reserved).to eq(BigDecimal('2.30'))
31
31
  end
32
32
 
33
33
  it "has a usd_available" do
34
- expect(subject.usd_available).to eq(BigDecimal('5.50'))
34
+ expect(balance.usd_available).to eq(BigDecimal('5.50'))
35
35
  end
36
36
 
37
37
  it "has a btc_available" do
38
- expect(subject.btc_available).to eq(BigDecimal('6.60'))
38
+ expect(balance.btc_available).to eq(BigDecimal('6.60'))
39
39
  end
40
40
 
41
41
  it "has a fee" do
42
- expect(subject.fee).to eq(BigDecimal('1.11'))
42
+ expect(balance.fee).to eq(BigDecimal('1.11'))
43
43
  end
44
44
 
45
45
  it "can be inspected" do
46
- expect { subject.inspect }.to_not raise_error
46
+ expect { balance.inspect }.to_not raise_error
47
47
  end
48
48
  end
@@ -1,33 +1,51 @@
1
1
  require_relative '../../../spec_helper'
2
2
 
3
3
  describe Bitstampede::Entities::Order do
4
- let(:order_hash){
5
- {
6
- "id" => "1",
7
- "datetime" => 1234567,
8
- "type" => 0,
9
- "price" => "1.23",
10
- "amount" => "10"
11
- }
12
- }
13
4
  subject{ described_class.new(order_hash) }
14
5
 
15
- it "has an id" do
16
- expect(subject.id).to eq(1)
17
- end
6
+ context "a successful order" do
7
+ let(:order_hash){
8
+ {
9
+ "id" => "1",
10
+ "datetime" => 1234567,
11
+ "type" => 0,
12
+ "price" => "1.23",
13
+ "amount" => "10"
14
+ }
15
+ }
18
16
 
19
- describe "type" do
20
- it "maps 0 to :buy" do
21
- expect(subject.type).to eq(:buy)
17
+ it "has an id" do
18
+ expect(subject.id).to eq(1)
22
19
  end
23
20
 
24
- it "maps 1 to :sell" do
25
- order = described_class.new(order_hash.merge({"type" => 1}))
26
- expect(order.type).to eq(:sell)
21
+ describe "type" do
22
+ it "maps 0 to :buy" do
23
+ expect(subject.type).to eq(:buy)
24
+ end
25
+
26
+ it "maps 1 to :sell" do
27
+ order = described_class.new(order_hash.merge({"type" => 1}))
28
+ expect(order.type).to eq(:sell)
29
+ end
30
+
31
+ it "raises InvalidTypeError for other values" do
32
+ expect { described_class.new(order_hash.merge({"type" => 2})) }.to raise_error(Bitstampede::Entities::Order::InvalidTypeError)
33
+ end
27
34
  end
35
+ end
36
+
37
+ context "an unsuccessful order" do
38
+ let(:order_hash){
39
+ # Don't get mad at me, not my fault bitstamp errors look like this
40
+ {
41
+ "error" => {
42
+ "__all__" => ["Minimum order size is $1"]
43
+ }
44
+ }
45
+ }
28
46
 
29
- it "raises InvalidTypeError for other values" do
30
- expect { described_class.new(order_hash.merge({"type" => 2})) }.to raise_error(Bitstampede::Entities::Order::InvalidTypeError)
47
+ it "raises an appropriate error" do
48
+ expect{ subject }.to raise_error(Bitstampede::StandardError, "Minimum order size is $1")
31
49
  end
32
50
  end
33
51
  end
@@ -1,7 +1,7 @@
1
1
  require_relative '../../spec_helper'
2
2
 
3
3
  describe Bitstampede::Mapper do
4
- subject { described_class.new }
4
+ subject(:mapper) { described_class.new }
5
5
  let(:json_object){ '{"foo": "bar"}' }
6
6
  let(:json_array){ '[{"foo": "bar"}]' }
7
7
 
@@ -13,12 +13,12 @@ describe Bitstampede::Mapper do
13
13
  end
14
14
 
15
15
  it "maps a balance API response into a Balance entity" do
16
- subject.map_balance(json_object)
16
+ mapper.map_balance(json_object)
17
17
  expect(Entities::Balance).to have_received(:new).with(json_parse(json_object))
18
18
  end
19
19
 
20
20
  it "returns the mapped Balance entity" do
21
- expect(subject.map_balance(json_object)).to eq(balance)
21
+ expect(mapper.map_balance(json_object)).to eq(balance)
22
22
  end
23
23
  end
24
24
 
@@ -30,15 +30,15 @@ describe Bitstampede::Mapper do
30
30
  end
31
31
 
32
32
  it "maps an open_orders API response into an array of Order entities" do
33
- subject.map_orders(json_array)
33
+ mapper.map_orders(json_array)
34
34
  expect(Entities::Order).to have_received(:new).with(json_parse(json_array)[0])
35
35
  end
36
36
  end
37
37
 
38
38
  describe '#map_cancel' do
39
39
  it "maps a cancel API response to a boolean" do
40
- expect(subject.map_cancel('"true"')).to eq(true)
41
- expect(subject.map_cancel('"false"')).to eq(false)
40
+ expect(mapper.map_cancel('"true"')).to eq(true)
41
+ expect(mapper.map_cancel('"false"')).to eq(false)
42
42
  end
43
43
  end
44
44
  end
@@ -2,7 +2,7 @@ require_relative '../../spec_helper'
2
2
 
3
3
  describe Bitstampede::Net do
4
4
  let(:client){ double }
5
- subject { described_class.new(client) }
5
+ subject(:net) { described_class.new(client) }
6
6
 
7
7
  before do
8
8
  client.stub(:secret).and_return(1)
@@ -10,15 +10,15 @@ describe Bitstampede::Net do
10
10
  end
11
11
 
12
12
  it 'gets instantiated with a client' do
13
- expect(subject.client).to eq(client)
13
+ expect(net.client).to eq(client)
14
14
  end
15
15
 
16
16
  it 'defers to its client for secret' do
17
- expect(subject.secret).to eq(1)
17
+ expect(net.secret).to eq(1)
18
18
  end
19
19
 
20
20
  it 'defers to its client for key' do
21
- expect(subject.key).to eq(2)
21
+ expect(net.key).to eq(2)
22
22
  end
23
23
 
24
24
  describe '#post' do
@@ -36,7 +36,7 @@ describe Bitstampede::Net do
36
36
  end
37
37
 
38
38
  it "queries the appropriate endpoint and returns its body as a string" do
39
- expect(json_parse(subject.post('balance'))).to eq(json_parse(example_balance))
39
+ expect(json_parse(net.post('balance'))).to eq(json_parse(example_balance))
40
40
  end
41
41
  end
42
42
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: bitstampede
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.5
4
+ version: 0.1.6
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2013-07-01 00:00:00.000000000 Z
12
+ date: 2013-07-08 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: httparty
@@ -191,7 +191,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
191
191
  version: '0'
192
192
  segments:
193
193
  - 0
194
- hash: 517563183236456493
194
+ hash: -2456329211082367398
195
195
  required_rubygems_version: !ruby/object:Gem::Requirement
196
196
  none: false
197
197
  requirements:
@@ -200,7 +200,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
200
200
  version: '0'
201
201
  segments:
202
202
  - 0
203
- hash: 517563183236456493
203
+ hash: -2456329211082367398
204
204
  requirements: []
205
205
  rubyforge_project:
206
206
  rubygems_version: 1.8.25