bitstampede 0.1.5 → 0.1.6

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.
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