tastytrade 0.2.0 → 0.3.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 (60) hide show
  1. checksums.yaml +4 -4
  2. data/.claude/commands/plan.md +13 -0
  3. data/.claude/commands/release-pr.md +12 -0
  4. data/CHANGELOG.md +170 -0
  5. data/README.md +424 -3
  6. data/ROADMAP.md +17 -17
  7. data/lib/tastytrade/cli/history_formatter.rb +304 -0
  8. data/lib/tastytrade/cli/orders.rb +749 -0
  9. data/lib/tastytrade/cli/positions_formatter.rb +114 -0
  10. data/lib/tastytrade/cli.rb +701 -12
  11. data/lib/tastytrade/cli_helpers.rb +111 -14
  12. data/lib/tastytrade/client.rb +7 -0
  13. data/lib/tastytrade/file_store.rb +83 -0
  14. data/lib/tastytrade/instruments/equity.rb +42 -0
  15. data/lib/tastytrade/models/account.rb +160 -2
  16. data/lib/tastytrade/models/account_balance.rb +46 -0
  17. data/lib/tastytrade/models/buying_power_effect.rb +61 -0
  18. data/lib/tastytrade/models/live_order.rb +272 -0
  19. data/lib/tastytrade/models/order_response.rb +106 -0
  20. data/lib/tastytrade/models/order_status.rb +84 -0
  21. data/lib/tastytrade/models/trading_status.rb +200 -0
  22. data/lib/tastytrade/models/transaction.rb +151 -0
  23. data/lib/tastytrade/models.rb +6 -0
  24. data/lib/tastytrade/order.rb +191 -0
  25. data/lib/tastytrade/order_validator.rb +355 -0
  26. data/lib/tastytrade/session.rb +26 -1
  27. data/lib/tastytrade/session_manager.rb +43 -14
  28. data/lib/tastytrade/version.rb +1 -1
  29. data/lib/tastytrade.rb +43 -0
  30. data/spec/exe/tastytrade_spec.rb +1 -1
  31. data/spec/spec_helper.rb +72 -0
  32. data/spec/tastytrade/cli/positions_spec.rb +267 -0
  33. data/spec/tastytrade/cli_auth_spec.rb +5 -0
  34. data/spec/tastytrade/cli_env_login_spec.rb +199 -0
  35. data/spec/tastytrade/cli_helpers_spec.rb +3 -26
  36. data/spec/tastytrade/cli_orders_spec.rb +168 -0
  37. data/spec/tastytrade/cli_status_spec.rb +153 -164
  38. data/spec/tastytrade/file_store_spec.rb +126 -0
  39. data/spec/tastytrade/models/account_balance_spec.rb +103 -0
  40. data/spec/tastytrade/models/account_order_history_spec.rb +229 -0
  41. data/spec/tastytrade/models/account_order_management_spec.rb +271 -0
  42. data/spec/tastytrade/models/account_place_order_spec.rb +125 -0
  43. data/spec/tastytrade/models/account_spec.rb +86 -15
  44. data/spec/tastytrade/models/buying_power_effect_spec.rb +250 -0
  45. data/spec/tastytrade/models/live_order_json_spec.rb +144 -0
  46. data/spec/tastytrade/models/live_order_spec.rb +295 -0
  47. data/spec/tastytrade/models/order_response_spec.rb +96 -0
  48. data/spec/tastytrade/models/order_status_spec.rb +113 -0
  49. data/spec/tastytrade/models/trading_status_spec.rb +260 -0
  50. data/spec/tastytrade/models/transaction_spec.rb +236 -0
  51. data/spec/tastytrade/order_edge_cases_spec.rb +163 -0
  52. data/spec/tastytrade/order_spec.rb +201 -0
  53. data/spec/tastytrade/order_validator_spec.rb +347 -0
  54. data/spec/tastytrade/session_env_spec.rb +169 -0
  55. data/spec/tastytrade/session_manager_spec.rb +43 -33
  56. data/vcr_implementation_plan.md +403 -0
  57. data/vcr_implementation_research.md +330 -0
  58. metadata +50 -18
  59. data/lib/tastytrade/keyring_store.rb +0 -72
  60. data/spec/tastytrade/keyring_store_spec.rb +0 -168
@@ -1,168 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require "spec_helper"
4
- require "tastytrade/keyring_store"
5
-
6
- RSpec.describe Tastytrade::KeyringStore do
7
- let(:mock_backend) { instance_double(Keyring) }
8
-
9
- before do
10
- # Reset the backend before each test
11
- described_class.instance_variable_set(:@backend, nil)
12
- allow(Keyring).to receive(:new).and_return(mock_backend)
13
- # Suppress warnings during tests
14
- allow(described_class).to receive(:warn)
15
- end
16
-
17
- describe ".set" do
18
- it "stores a credential successfully" do
19
- expect(mock_backend).to receive(:set_password)
20
- .with("tastytrade-ruby", "test_key", "test_value")
21
-
22
- expect(described_class.set("test_key", "test_value")).to be true
23
- end
24
-
25
- it "returns false for nil key" do
26
- expect(mock_backend).not_to receive(:set_password)
27
- expect(described_class.set(nil, "value")).to be false
28
- end
29
-
30
- it "returns false for nil value" do
31
- expect(mock_backend).not_to receive(:set_password)
32
- expect(described_class.set("key", nil)).to be false
33
- end
34
-
35
- it "handles errors gracefully" do
36
- expect(mock_backend).to receive(:set_password)
37
- .and_raise(StandardError, "Keyring error")
38
-
39
- expect(described_class.set("key", "value")).to be false
40
- end
41
-
42
- it "converts symbols to strings" do
43
- expect(mock_backend).to receive(:set_password)
44
- .with("tastytrade-ruby", "symbol_key", "value")
45
-
46
- described_class.set(:symbol_key, "value")
47
- end
48
- end
49
-
50
- describe ".get" do
51
- it "retrieves a credential successfully" do
52
- expect(mock_backend).to receive(:get_password)
53
- .with("tastytrade-ruby", "test_key")
54
- .and_return("test_value")
55
-
56
- expect(described_class.get("test_key")).to eq("test_value")
57
- end
58
-
59
- it "returns nil for nil key" do
60
- expect(mock_backend).not_to receive(:get_password)
61
- expect(described_class.get(nil)).to be_nil
62
- end
63
-
64
- it "handles errors gracefully" do
65
- expect(mock_backend).to receive(:get_password)
66
- .and_raise(StandardError, "Keyring error")
67
-
68
- expect(described_class.get("key")).to be_nil
69
- end
70
-
71
- it "converts symbols to strings" do
72
- expect(mock_backend).to receive(:get_password)
73
- .with("tastytrade-ruby", "symbol_key")
74
- .and_return("value")
75
-
76
- expect(described_class.get(:symbol_key)).to eq("value")
77
- end
78
- end
79
-
80
- describe ".delete" do
81
- it "deletes a credential successfully" do
82
- expect(mock_backend).to receive(:delete_password)
83
- .with("tastytrade-ruby", "test_key")
84
-
85
- expect(described_class.delete("test_key")).to be true
86
- end
87
-
88
- it "returns false for nil key" do
89
- expect(mock_backend).not_to receive(:delete_password)
90
- expect(described_class.delete(nil)).to be false
91
- end
92
-
93
- it "handles errors gracefully" do
94
- expect(mock_backend).to receive(:delete_password)
95
- .and_raise(StandardError, "Keyring error")
96
-
97
- expect(described_class.delete("key")).to be false
98
- end
99
- end
100
-
101
- describe ".available?" do
102
- context "when keyring is available" do
103
- it "returns true" do
104
- expect(described_class.available?).to be true
105
- end
106
- end
107
-
108
- context "when keyring is not available" do
109
- before do
110
- allow(Keyring).to receive(:new).and_raise(StandardError, "No backend")
111
- end
112
-
113
- it "returns false" do
114
- expect(described_class.available?).to be false
115
- end
116
- end
117
-
118
- context "when backend is nil" do
119
- before do
120
- allow(Keyring).to receive(:new).and_return(nil)
121
- end
122
-
123
- it "returns false" do
124
- expect(described_class.available?).to be false
125
- end
126
- end
127
- end
128
-
129
- describe "error messages" do
130
- context "when warnings are not suppressed" do
131
- before do
132
- allow(described_class).to receive(:warn).and_call_original
133
- end
134
-
135
- it "warns on set failure" do
136
- expect(mock_backend).to receive(:set_password)
137
- .and_raise(StandardError, "Set error")
138
-
139
- expect { described_class.set("key", "value") }
140
- .to output(/Failed to store credential: Set error/).to_stderr
141
- end
142
-
143
- it "warns on get failure" do
144
- expect(mock_backend).to receive(:get_password)
145
- .and_raise(StandardError, "Get error")
146
-
147
- expect { described_class.get("key") }
148
- .to output(/Failed to retrieve credential: Get error/).to_stderr
149
- end
150
-
151
- it "warns on delete failure" do
152
- expect(mock_backend).to receive(:delete_password)
153
- .and_raise(StandardError, "Delete error")
154
-
155
- expect { described_class.delete("key") }
156
- .to output(/Failed to delete credential: Delete error/).to_stderr
157
- end
158
-
159
- it "warns when keyring is not available" do
160
- allow(Keyring).to receive(:new).and_raise(StandardError, "No backend")
161
-
162
- # Force backend initialization
163
- expect { described_class.send(:backend) }
164
- .to output(/Keyring not available: No backend/).to_stderr
165
- end
166
- end
167
- end
168
- end