honeymaker 0.1.0 → 0.2.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 (73) hide show
  1. checksums.yaml +4 -4
  2. data/honeymaker-0.1.0.gem +0 -0
  3. data/lib/honeymaker/client.rb +74 -0
  4. data/lib/honeymaker/clients/binance.rb +240 -0
  5. data/lib/honeymaker/clients/binance_us.rb +9 -0
  6. data/lib/honeymaker/clients/bingx.rb +105 -0
  7. data/lib/honeymaker/clients/bitget.rb +128 -0
  8. data/lib/honeymaker/clients/bitmart.rb +117 -0
  9. data/lib/honeymaker/clients/bitrue.rb +114 -0
  10. data/lib/honeymaker/clients/bitvavo.rb +136 -0
  11. data/lib/honeymaker/clients/bybit.rb +136 -0
  12. data/lib/honeymaker/clients/coinbase.rb +184 -0
  13. data/lib/honeymaker/clients/gemini.rb +81 -0
  14. data/lib/honeymaker/clients/hyperliquid.rb +42 -0
  15. data/lib/honeymaker/clients/kraken.rb +132 -0
  16. data/lib/honeymaker/clients/kucoin.rb +147 -0
  17. data/lib/honeymaker/clients/mexc.rb +136 -0
  18. data/lib/honeymaker/exchanges/binance.rb +11 -17
  19. data/lib/honeymaker/exchanges/bitget.rb +2 -2
  20. data/lib/honeymaker/exchanges/bitrue.rb +6 -16
  21. data/lib/honeymaker/exchanges/bitvavo.rb +2 -2
  22. data/lib/honeymaker/exchanges/bybit.rb +2 -2
  23. data/lib/honeymaker/exchanges/coinbase.rb +5 -9
  24. data/lib/honeymaker/exchanges/gemini.rb +4 -6
  25. data/lib/honeymaker/exchanges/kraken.rb +5 -9
  26. data/lib/honeymaker/exchanges/kucoin.rb +2 -2
  27. data/lib/honeymaker/exchanges/mexc.rb +11 -17
  28. data/lib/honeymaker/utils.rb +9 -0
  29. data/lib/honeymaker/version.rb +1 -1
  30. data/lib/honeymaker.rb +38 -0
  31. data/test/fixtures/bingx_symbols.json +26 -0
  32. data/test/fixtures/bitget_symbols.json +28 -0
  33. data/test/fixtures/bitmart_symbols.json +26 -0
  34. data/test/fixtures/bitrue_exchange_info.json +34 -0
  35. data/test/fixtures/bitvavo_markets.json +16 -0
  36. data/test/fixtures/bybit_instruments.json +23 -0
  37. data/test/fixtures/coinbase_products.json +24 -0
  38. data/test/fixtures/gemini_symbol_detail.json +9 -0
  39. data/test/fixtures/gemini_symbols.json +1 -0
  40. data/test/fixtures/hyperliquid_spot_meta.json +12 -0
  41. data/test/fixtures/kucoin_symbols.json +17 -0
  42. data/test/fixtures/mexc_exchange_info.json +40 -0
  43. data/test/honeymaker/client_test.rb +53 -0
  44. data/test/honeymaker/clients/binance_client_test.rb +80 -0
  45. data/test/honeymaker/clients/binance_us_client_test.rb +25 -0
  46. data/test/honeymaker/clients/bingx_client_test.rb +64 -0
  47. data/test/honeymaker/clients/bitget_client_test.rb +85 -0
  48. data/test/honeymaker/clients/bitmart_client_test.rb +78 -0
  49. data/test/honeymaker/clients/bitrue_client_test.rb +63 -0
  50. data/test/honeymaker/clients/bitvavo_client_test.rb +87 -0
  51. data/test/honeymaker/clients/bybit_client_test.rb +84 -0
  52. data/test/honeymaker/clients/coinbase_client_test.rb +118 -0
  53. data/test/honeymaker/clients/gemini_client_test.rb +71 -0
  54. data/test/honeymaker/clients/honeymaker_client_registry_test.rb +44 -0
  55. data/test/honeymaker/clients/hyperliquid_client_test.rb +53 -0
  56. data/test/honeymaker/clients/kraken_client_test.rb +70 -0
  57. data/test/honeymaker/clients/kucoin_client_test.rb +88 -0
  58. data/test/honeymaker/clients/mexc_client_test.rb +75 -0
  59. data/test/honeymaker/exchanges/binance_us_test.rb +40 -0
  60. data/test/honeymaker/exchanges/bingx_test.rb +53 -0
  61. data/test/honeymaker/exchanges/bitget_test.rb +52 -0
  62. data/test/honeymaker/exchanges/bitmart_test.rb +52 -0
  63. data/test/honeymaker/exchanges/bitrue_test.rb +53 -0
  64. data/test/honeymaker/exchanges/bitvavo_test.rb +52 -0
  65. data/test/honeymaker/exchanges/bybit_test.rb +43 -0
  66. data/test/honeymaker/exchanges/coinbase_test.rb +52 -0
  67. data/test/honeymaker/exchanges/gemini_test.rb +48 -0
  68. data/test/honeymaker/exchanges/hyperliquid_test.rb +52 -0
  69. data/test/honeymaker/exchanges/kucoin_test.rb +43 -0
  70. data/test/honeymaker/exchanges/mexc_test.rb +64 -0
  71. data/test/honeymaker/utils_test.rb +38 -0
  72. data/test/test_helper.rb +1 -0
  73. metadata +74 -3
@@ -0,0 +1,70 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "test_helper"
4
+
5
+ class Honeymaker::Clients::KrakenTest < Minitest::Test
6
+ def setup
7
+ @client = Honeymaker::Clients::Kraken.new(
8
+ api_key: "test_key",
9
+ api_secret: Base64.strict_encode64("test_secret_key_1234567890123456")
10
+ )
11
+ end
12
+
13
+ def test_url
14
+ assert_equal "https://api.kraken.com", Honeymaker::Clients::Kraken::URL
15
+ end
16
+
17
+ def test_get_tradable_asset_pairs
18
+ stub_connection(:get, { "error" => [], "result" => { "XBTUSDT" => { "altname" => "XBTUSDT" } } })
19
+ result = @client.get_tradable_asset_pairs
20
+ assert result.success?
21
+ assert result.data["result"].key?("XBTUSDT")
22
+ end
23
+
24
+ def test_get_ticker_information
25
+ stub_connection(:get, { "error" => [], "result" => { "XBTUSDT" => { "a" => ["50000"] } } })
26
+ result = @client.get_ticker_information(pair: "XBTUSDT")
27
+ assert result.success?
28
+ end
29
+
30
+ def test_add_order
31
+ stub_connection(:post, { "error" => [], "result" => { "txid" => ["ORDER-123"] } })
32
+ result = @client.add_order(ordertype: "market", type: "buy", volume: "0.001", pair: "XBTUSDT")
33
+ assert result.success?
34
+ assert_equal ["ORDER-123"], result.data["result"]["txid"]
35
+ end
36
+
37
+ def test_cancel_order
38
+ stub_connection(:post, { "error" => [], "result" => { "count" => 1 } })
39
+ result = @client.cancel_order(txid: "ORDER-123")
40
+ assert result.success?
41
+ end
42
+
43
+ def test_get_extended_balance
44
+ stub_connection(:post, { "error" => [], "result" => { "XXBT" => { "balance" => "0.5" } } })
45
+ result = @client.get_extended_balance
46
+ assert result.success?
47
+ end
48
+
49
+ def test_private_headers_produce_signature
50
+ headers = @client.send(:private_headers, "/0/private/Balance", "nonce=12345")
51
+ assert headers.key?(:"API-Key")
52
+ assert headers.key?(:"API-Sign")
53
+ assert_equal "test_key", headers[:"API-Key"]
54
+ end
55
+
56
+ def test_public_headers_no_auth
57
+ client = Honeymaker::Clients::Kraken.new
58
+ headers = client.send(:public_headers)
59
+ refute headers.key?(:"API-Key")
60
+ end
61
+
62
+ private
63
+
64
+ def stub_connection(method, body)
65
+ response = stub(body: body)
66
+ connection = stub
67
+ connection.stubs(method).returns(response)
68
+ @client.instance_variable_set(:@connection, connection)
69
+ end
70
+ end
@@ -0,0 +1,88 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "test_helper"
4
+
5
+ class Honeymaker::Clients::KucoinTest < Minitest::Test
6
+ def setup
7
+ @client = Honeymaker::Clients::Kucoin.new(
8
+ api_key: "test_key", api_secret: "test_secret", passphrase: "test_pass"
9
+ )
10
+ end
11
+
12
+ def test_url
13
+ assert_equal "https://api.kucoin.com", Honeymaker::Clients::Kucoin::URL
14
+ end
15
+
16
+ def test_accepts_passphrase
17
+ assert_equal "test_pass", @client.passphrase
18
+ end
19
+
20
+ def test_get_symbols
21
+ stub_connection(:get, { "data" => [{ "symbol" => "BTC-USDT" }] })
22
+ result = @client.get_symbols
23
+ assert result.success?
24
+ end
25
+
26
+ def test_get_all_tickers
27
+ stub_connection(:get, { "data" => { "ticker" => [] } })
28
+ result = @client.get_all_tickers
29
+ assert result.success?
30
+ end
31
+
32
+ def test_get_accounts
33
+ stub_connection(:get, { "data" => [{ "currency" => "BTC" }] })
34
+ result = @client.get_accounts
35
+ assert result.success?
36
+ end
37
+
38
+ def test_place_order
39
+ stub_connection(:post, { "data" => { "orderId" => "123" } })
40
+ result = @client.place_order(client_oid: "c1", side: "buy", symbol: "BTC-USDT", type: "market", funds: "100")
41
+ assert result.success?
42
+ end
43
+
44
+ def test_get_order
45
+ stub_connection(:get, { "data" => { "id" => "123", "isActive" => false } })
46
+ result = @client.get_order(order_id: "123")
47
+ assert result.success?
48
+ end
49
+
50
+ def test_cancel_order
51
+ stub_connection(:delete, { "data" => { "cancelledOrderIds" => ["123"] } })
52
+ result = @client.cancel_order(order_id: "123")
53
+ assert result.success?
54
+ end
55
+
56
+ def test_withdraw
57
+ stub_connection(:post, { "data" => { "withdrawalId" => "w1" } })
58
+ result = @client.withdraw(currency: "BTC", address: "addr", amount: "0.1")
59
+ assert result.success?
60
+ end
61
+
62
+ def test_signed_headers_include_passphrase_and_version
63
+ ts = "1234567890"
64
+ headers = @client.send(:signed_headers, ts, "payload")
65
+ assert_equal "test_key", headers[:"KC-API-KEY"]
66
+ assert_equal "2", headers[:"KC-API-KEY-VERSION"]
67
+ assert headers.key?(:"KC-API-SIGN")
68
+ assert headers.key?(:"KC-API-PASSPHRASE")
69
+ end
70
+
71
+ def test_passphrase_is_signed
72
+ ts = "1234567890"
73
+ headers = @client.send(:signed_headers, ts, "payload")
74
+ # KuCoin v2 signs the passphrase with the secret
75
+ raw_passphrase = "test_pass"
76
+ expected = Base64.strict_encode64(OpenSSL::HMAC.digest("sha256", "test_secret", raw_passphrase))
77
+ assert_equal expected, headers[:"KC-API-PASSPHRASE"]
78
+ end
79
+
80
+ private
81
+
82
+ def stub_connection(method, body)
83
+ response = stub(body: body)
84
+ connection = stub
85
+ connection.stubs(method).returns(response)
86
+ @client.instance_variable_set(:@connection, connection)
87
+ end
88
+ end
@@ -0,0 +1,75 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "test_helper"
4
+
5
+ class Honeymaker::Clients::MexcTest < Minitest::Test
6
+ def setup
7
+ @client = Honeymaker::Clients::Mexc.new(api_key: "test_key", api_secret: "test_secret")
8
+ end
9
+
10
+ def test_url
11
+ assert_equal "https://api.mexc.com", Honeymaker::Clients::Mexc::URL
12
+ end
13
+
14
+ def test_exchange_information
15
+ stub_connection(:get, { "symbols" => [{ "symbol" => "BTCUSDT" }] })
16
+ result = @client.exchange_information
17
+ assert result.success?
18
+ end
19
+
20
+ def test_symbol_price_ticker
21
+ stub_connection(:get, { "symbol" => "BTCUSDT", "price" => "50000" })
22
+ result = @client.symbol_price_ticker(symbol: "BTCUSDT")
23
+ assert result.success?
24
+ end
25
+
26
+ def test_account_information
27
+ stub_connection(:get, { "balances" => [{ "asset" => "BTC" }] })
28
+ result = @client.account_information
29
+ assert result.success?
30
+ end
31
+
32
+ def test_new_order
33
+ stub_connection(:post, { "orderId" => "123" })
34
+ result = @client.new_order(symbol: "BTCUSDT", side: "BUY", type: "MARKET", quantity: "0.001")
35
+ assert result.success?
36
+ end
37
+
38
+ def test_query_order
39
+ stub_connection(:get, { "orderId" => "123", "status" => "FILLED" })
40
+ result = @client.query_order(symbol: "BTCUSDT", order_id: "123")
41
+ assert result.success?
42
+ end
43
+
44
+ def test_cancel_order
45
+ stub_connection(:delete, { "orderId" => "123" })
46
+ result = @client.cancel_order(symbol: "BTCUSDT", order_id: "123")
47
+ assert result.success?
48
+ end
49
+
50
+ def test_withdraw
51
+ stub_connection(:post, { "id" => "w1" })
52
+ result = @client.withdraw(coin: "BTC", address: "addr", amount: "0.1")
53
+ assert result.success?
54
+ end
55
+
56
+ def test_headers_include_api_key
57
+ headers = @client.send(:headers)
58
+ assert_equal "test_key", headers[:"X-MEXC-APIKEY"]
59
+ end
60
+
61
+ def test_sign_params
62
+ sig = @client.send(:sign_params, { symbol: "BTCUSDT", timestamp: 1234567890 })
63
+ assert sig.is_a?(String)
64
+ assert_equal 64, sig.length
65
+ end
66
+
67
+ private
68
+
69
+ def stub_connection(method, body)
70
+ response = stub(body: body)
71
+ connection = stub
72
+ connection.stubs(method).returns(response)
73
+ @client.instance_variable_set(:@connection, connection)
74
+ end
75
+ end
@@ -0,0 +1,40 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "test_helper"
4
+
5
+ class Honeymaker::Exchanges::BinanceUsTest < Minitest::Test
6
+ include FixtureHelper
7
+
8
+ def setup
9
+ @exchange = Honeymaker::Exchanges::BinanceUs.new
10
+ end
11
+
12
+ def test_inherits_from_binance
13
+ assert_kind_of Honeymaker::Exchanges::Binance, @exchange
14
+ end
15
+
16
+ def test_uses_binance_us_url
17
+ assert_equal "https://api.binance.us", Honeymaker::Exchanges::BinanceUs::BASE_URL
18
+ end
19
+
20
+ def test_get_tickers_info_parses_response
21
+ body = load_fixture("binance_exchange_info.json")
22
+ stub_connection(body)
23
+
24
+ result = @exchange.get_tickers_info
25
+
26
+ assert result.success?
27
+ ticker = result.data.first
28
+ assert_equal "BTCUSDT", ticker[:ticker]
29
+ assert_equal "BTC", ticker[:base]
30
+ end
31
+
32
+ private
33
+
34
+ def stub_connection(body)
35
+ response = stub(body: body)
36
+ connection = stub
37
+ connection.stubs(:get).with { |_, &block| block&.call(OpenStruct.new(params: {})); true }.returns(response)
38
+ @exchange.instance_variable_set(:@connection, connection)
39
+ end
40
+ end
@@ -0,0 +1,53 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "test_helper"
4
+
5
+ class Honeymaker::Exchanges::BingXTest < Minitest::Test
6
+ include FixtureHelper
7
+
8
+ def setup
9
+ @exchange = Honeymaker::Exchanges::BingX.new
10
+ end
11
+
12
+ def test_get_tickers_info_parses_response
13
+ body = load_fixture("bingx_symbols.json")
14
+ stub_connection(body)
15
+
16
+ result = @exchange.get_tickers_info
17
+
18
+ assert result.success?
19
+ # "INVALID" has no dash so it's skipped
20
+ assert_equal 1, result.data.size
21
+
22
+ ticker = result.data.first
23
+ assert_equal "BTC-USDT", ticker[:ticker]
24
+ assert_equal "BTC", ticker[:base]
25
+ assert_equal "USDT", ticker[:quote]
26
+ assert_equal "0.00001", ticker[:minimum_base_size]
27
+ assert_equal "1", ticker[:minimum_quote_size]
28
+ assert_equal "500", ticker[:maximum_base_size]
29
+ assert_equal 5, ticker[:base_decimals]
30
+ assert_equal 2, ticker[:quote_decimals]
31
+ assert_equal 2, ticker[:price_decimals]
32
+ assert ticker[:available]
33
+ end
34
+
35
+ def test_skips_symbols_without_dash
36
+ body = load_fixture("bingx_symbols.json")
37
+ stub_connection(body)
38
+
39
+ result = @exchange.get_tickers_info
40
+
41
+ tickers = result.data.map { |t| t[:ticker] }
42
+ refute_includes tickers, "INVALID"
43
+ end
44
+
45
+ private
46
+
47
+ def stub_connection(body)
48
+ response = stub(body: body)
49
+ connection = stub
50
+ connection.stubs(:get).returns(response)
51
+ @exchange.instance_variable_set(:@connection, connection)
52
+ end
53
+ end
@@ -0,0 +1,52 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "test_helper"
4
+
5
+ class Honeymaker::Exchanges::BitgetTest < Minitest::Test
6
+ include FixtureHelper
7
+
8
+ def setup
9
+ @exchange = Honeymaker::Exchanges::Bitget.new
10
+ end
11
+
12
+ def test_get_tickers_info_parses_response
13
+ body = load_fixture("bitget_symbols.json")
14
+ stub_connection(body)
15
+
16
+ result = @exchange.get_tickers_info
17
+
18
+ assert result.success?
19
+ assert_equal 2, result.data.size
20
+
21
+ ticker = result.data.first
22
+ assert_equal "BTCUSDT", ticker[:ticker]
23
+ assert_equal "BTC", ticker[:base]
24
+ assert_equal "USDT", ticker[:quote]
25
+ assert_equal "0.00001", ticker[:minimum_base_size]
26
+ assert_equal "5", ticker[:minimum_quote_size]
27
+ assert_equal "9000", ticker[:maximum_base_size]
28
+ assert_equal 6, ticker[:base_decimals]
29
+ assert_equal 8, ticker[:quote_decimals]
30
+ assert_equal 2, ticker[:price_decimals]
31
+ assert ticker[:available]
32
+ end
33
+
34
+ def test_offline_symbol_not_available
35
+ body = load_fixture("bitget_symbols.json")
36
+ stub_connection(body)
37
+
38
+ result = @exchange.get_tickers_info
39
+
40
+ eth = result.data.find { |t| t[:ticker] == "ETHUSDT" }
41
+ refute eth[:available]
42
+ end
43
+
44
+ private
45
+
46
+ def stub_connection(body)
47
+ response = stub(body: body)
48
+ connection = stub
49
+ connection.stubs(:get).returns(response)
50
+ @exchange.instance_variable_set(:@connection, connection)
51
+ end
52
+ end
@@ -0,0 +1,52 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "test_helper"
4
+
5
+ class Honeymaker::Exchanges::BitMartTest < Minitest::Test
6
+ include FixtureHelper
7
+
8
+ def setup
9
+ @exchange = Honeymaker::Exchanges::BitMart.new
10
+ end
11
+
12
+ def test_get_tickers_info_parses_response
13
+ body = load_fixture("bitmart_symbols.json")
14
+ stub_connection(body)
15
+
16
+ result = @exchange.get_tickers_info
17
+
18
+ assert result.success?
19
+ assert_equal 2, result.data.size
20
+
21
+ ticker = result.data.first
22
+ assert_equal "BTC_USDT", ticker[:ticker]
23
+ assert_equal "BTC", ticker[:base]
24
+ assert_equal "USDT", ticker[:quote]
25
+ assert_equal "0.00001", ticker[:minimum_base_size]
26
+ assert_equal "5", ticker[:minimum_quote_size]
27
+ assert_nil ticker[:maximum_base_size]
28
+ assert_equal 5, ticker[:base_decimals]
29
+ assert_equal 2, ticker[:quote_decimals]
30
+ assert_equal 2, ticker[:price_decimals]
31
+ assert ticker[:available]
32
+ end
33
+
34
+ def test_pre_trade_not_available
35
+ body = load_fixture("bitmart_symbols.json")
36
+ stub_connection(body)
37
+
38
+ result = @exchange.get_tickers_info
39
+
40
+ eth = result.data.find { |t| t[:ticker] == "ETH_USDT" }
41
+ refute eth[:available]
42
+ end
43
+
44
+ private
45
+
46
+ def stub_connection(body)
47
+ response = stub(body: body)
48
+ connection = stub
49
+ connection.stubs(:get).returns(response)
50
+ @exchange.instance_variable_set(:@connection, connection)
51
+ end
52
+ end
@@ -0,0 +1,53 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "test_helper"
4
+
5
+ class Honeymaker::Exchanges::BitrueTest < Minitest::Test
6
+ include FixtureHelper
7
+
8
+ def setup
9
+ @exchange = Honeymaker::Exchanges::Bitrue.new
10
+ end
11
+
12
+ def test_get_tickers_info_parses_response
13
+ body = load_fixture("bitrue_exchange_info.json")
14
+ stub_connection(body)
15
+
16
+ result = @exchange.get_tickers_info
17
+
18
+ assert result.success?
19
+ assert_equal 2, result.data.size
20
+
21
+ ticker = result.data.first
22
+ assert_equal "BTCUSDT", ticker[:ticker]
23
+ assert_equal "BTC", ticker[:base]
24
+ assert_equal "USDT", ticker[:quote]
25
+ assert_equal "0.00001", ticker[:minimum_base_size]
26
+ assert_equal "5", ticker[:minimum_quote_size]
27
+ assert_equal "9000", ticker[:maximum_base_size]
28
+ assert_equal 5, ticker[:base_decimals]
29
+ assert_equal 2, ticker[:quote_decimals]
30
+ assert_equal 2, ticker[:price_decimals]
31
+ assert ticker[:available]
32
+ end
33
+
34
+ def test_falls_back_to_precision_fields_when_no_filters
35
+ body = load_fixture("bitrue_exchange_info.json")
36
+ stub_connection(body)
37
+
38
+ result = @exchange.get_tickers_info
39
+
40
+ eth = result.data.find { |t| t[:ticker] == "ETHUSDT" }
41
+ assert_equal 6, eth[:base_decimals]
42
+ assert_equal 2, eth[:price_decimals]
43
+ end
44
+
45
+ private
46
+
47
+ def stub_connection(body)
48
+ response = stub(body: body)
49
+ connection = stub
50
+ connection.stubs(:get).returns(response)
51
+ @exchange.instance_variable_set(:@connection, connection)
52
+ end
53
+ end
@@ -0,0 +1,52 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "test_helper"
4
+
5
+ class Honeymaker::Exchanges::BitvavoTest < Minitest::Test
6
+ include FixtureHelper
7
+
8
+ def setup
9
+ @exchange = Honeymaker::Exchanges::Bitvavo.new
10
+ end
11
+
12
+ def test_get_tickers_info_parses_response
13
+ body = load_fixture("bitvavo_markets.json")
14
+ stub_connection(body)
15
+
16
+ result = @exchange.get_tickers_info
17
+
18
+ assert result.success?
19
+ assert_equal 2, result.data.size
20
+
21
+ ticker = result.data.first
22
+ assert_equal "BTC-EUR", ticker[:ticker]
23
+ assert_equal "BTC", ticker[:base]
24
+ assert_equal "EUR", ticker[:quote]
25
+ assert_equal "0.00001", ticker[:minimum_base_size]
26
+ assert_equal "5", ticker[:minimum_quote_size]
27
+ assert_nil ticker[:maximum_base_size]
28
+ assert_equal 5, ticker[:base_decimals]
29
+ assert_equal 5, ticker[:quote_decimals]
30
+ assert_equal 5, ticker[:price_decimals]
31
+ assert ticker[:available]
32
+ end
33
+
34
+ def test_halted_market_not_available
35
+ body = load_fixture("bitvavo_markets.json")
36
+ stub_connection(body)
37
+
38
+ result = @exchange.get_tickers_info
39
+
40
+ eth = result.data.find { |t| t[:ticker] == "ETH-EUR" }
41
+ refute eth[:available]
42
+ end
43
+
44
+ private
45
+
46
+ def stub_connection(body)
47
+ response = stub(body: body)
48
+ connection = stub
49
+ connection.stubs(:get).returns(response)
50
+ @exchange.instance_variable_set(:@connection, connection)
51
+ end
52
+ end
@@ -0,0 +1,43 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "test_helper"
4
+
5
+ class Honeymaker::Exchanges::BybitTest < Minitest::Test
6
+ include FixtureHelper
7
+
8
+ def setup
9
+ @exchange = Honeymaker::Exchanges::Bybit.new
10
+ end
11
+
12
+ def test_get_tickers_info_parses_response
13
+ body = load_fixture("bybit_instruments.json")
14
+ stub_connection(body)
15
+
16
+ result = @exchange.get_tickers_info
17
+
18
+ assert result.success?
19
+ assert_equal 1, result.data.size
20
+
21
+ ticker = result.data.first
22
+ assert_equal "BTCUSDT", ticker[:ticker]
23
+ assert_equal "BTC", ticker[:base]
24
+ assert_equal "USDT", ticker[:quote]
25
+ assert_equal "0.000048", ticker[:minimum_base_size]
26
+ assert_equal "1", ticker[:minimum_quote_size]
27
+ assert_equal "71.73956243", ticker[:maximum_base_size]
28
+ assert_equal "4000000", ticker[:maximum_quote_size]
29
+ assert_equal 6, ticker[:base_decimals]
30
+ assert_equal 8, ticker[:quote_decimals]
31
+ assert_equal 2, ticker[:price_decimals]
32
+ assert ticker[:available]
33
+ end
34
+
35
+ private
36
+
37
+ def stub_connection(body)
38
+ response = stub(body: body)
39
+ connection = stub
40
+ connection.stubs(:get).with { |_, &block| block&.call(OpenStruct.new(params: {})); true }.returns(response)
41
+ @exchange.instance_variable_set(:@connection, connection)
42
+ end
43
+ end
@@ -0,0 +1,52 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "test_helper"
4
+
5
+ class Honeymaker::Exchanges::CoinbaseTest < Minitest::Test
6
+ include FixtureHelper
7
+
8
+ def setup
9
+ @exchange = Honeymaker::Exchanges::Coinbase.new
10
+ end
11
+
12
+ def test_get_tickers_info_parses_response
13
+ body = load_fixture("coinbase_products.json")
14
+ stub_connection(body)
15
+
16
+ result = @exchange.get_tickers_info
17
+
18
+ assert result.success?
19
+ # RENDER is blacklisted, so only BTC-USD should remain
20
+ assert_equal 1, result.data.size
21
+ ticker = result.data.first
22
+ assert_equal "BTC-USD", ticker[:ticker]
23
+ assert_equal "BTC", ticker[:base]
24
+ assert_equal "USD", ticker[:quote]
25
+ assert_equal "0.00000001", ticker[:minimum_base_size]
26
+ assert_equal "1", ticker[:minimum_quote_size]
27
+ assert_equal "3400", ticker[:maximum_base_size]
28
+ assert_equal 8, ticker[:base_decimals]
29
+ assert_equal 2, ticker[:quote_decimals]
30
+ assert_equal 2, ticker[:price_decimals]
31
+ assert ticker[:available]
32
+ end
33
+
34
+ def test_filters_blacklisted_assets
35
+ body = load_fixture("coinbase_products.json")
36
+ stub_connection(body)
37
+
38
+ result = @exchange.get_tickers_info
39
+
40
+ bases = result.data.map { |t| t[:base] }
41
+ refute_includes bases, "RENDER"
42
+ end
43
+
44
+ private
45
+
46
+ def stub_connection(body)
47
+ response = stub(body: body)
48
+ connection = stub
49
+ connection.stubs(:get).returns(response)
50
+ @exchange.instance_variable_set(:@connection, connection)
51
+ end
52
+ end
@@ -0,0 +1,48 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "test_helper"
4
+
5
+ class Honeymaker::Exchanges::GeminiTest < Minitest::Test
6
+ include FixtureHelper
7
+
8
+ def setup
9
+ @exchange = Honeymaker::Exchanges::Gemini.new
10
+ end
11
+
12
+ def test_get_tickers_info_parses_response
13
+ symbols_body = load_fixture("gemini_symbols.json")
14
+ detail_body = load_fixture("gemini_symbol_detail.json")
15
+
16
+ symbols_response = stub(body: symbols_body)
17
+ detail_response = stub(body: detail_body)
18
+ connection = stub
19
+ connection.stubs(:get).with("/v1/symbols").returns(symbols_response)
20
+ connection.stubs(:get).with { |path| path.start_with?("/v1/symbols/details/") }.returns(detail_response)
21
+ @exchange.instance_variable_set(:@connection, connection)
22
+
23
+ result = @exchange.get_tickers_info
24
+
25
+ assert result.success?
26
+ assert_equal 2, result.data.size
27
+
28
+ ticker = result.data.first
29
+ assert_equal "BTCUSD", ticker[:ticker]
30
+ assert_equal "BTC", ticker[:base]
31
+ assert_equal "USD", ticker[:quote]
32
+ assert_equal "0.00001", ticker[:minimum_base_size]
33
+ assert_equal "0", ticker[:minimum_quote_size]
34
+ assert_equal 8, ticker[:base_decimals]
35
+ assert_equal 2, ticker[:quote_decimals]
36
+ assert_equal 2, ticker[:price_decimals]
37
+ assert ticker[:available]
38
+ end
39
+
40
+ private
41
+
42
+ def stub_connection(body)
43
+ response = stub(body: body)
44
+ connection = stub
45
+ connection.stubs(:get).returns(response)
46
+ @exchange.instance_variable_set(:@connection, connection)
47
+ end
48
+ end