Skip to content

Commit b8a40d4

Browse files
authored
Merge pull request #8 from ib-ruby/specs
Specs
2 parents 794d002 + fc50e31 commit b8a40d4

File tree

5 files changed

+132
-39
lines changed

5 files changed

+132
-39
lines changed

lib/ib/constants.rb

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -205,7 +205,6 @@ module IB
205205
'NONE' => :none, # Used to indicate no hedge in :delta_neutral_order_type
206206
'None' => :none, # Used to indicate no hedge in :delta_neutral_order_type
207207
}.freeze
208-
209208
# Valid security types (sec_type attribute of IB::Contract)
210209
SECURITY_TYPES =
211210
{ 'BAG' => :bag,
@@ -223,7 +222,13 @@ module IB
223222
'OPT' => :option,
224223
'IOPT' => :dutch_option,
225224
'STK' => :stock,
226-
'WAR' => :warrant}.freeze
225+
'WAR' => :warrant,
226+
'ICU' => :icu,
227+
'ICS' => :ics,
228+
'BILL' => :bill,
229+
'BSK' => :basket,
230+
'FWD' => :forward,
231+
'FIXED' => :fixed }.freeze
227232

228233
# Obtain symbolic value from given property code:
229234
# VALUES[:side]['B'] -> :buy

lib/models/ib/contract.rb

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
require 'models/ib/contract_detail'
22
require 'models/ib/underlying'
33

4+
5+
46
module IB
57
class Contract < IB::Model
68
include BaseProperties
@@ -203,6 +205,10 @@ def serialize_ib_ruby
203205
serialize_long.join(":")
204206
end
205207

208+
# extracts essential attributes of the contract,
209+
# and returns a new contract.
210+
#
211+
# the link to contract-details is __not__ maintained.
206212
def essential
207213

208214
self_attributes = [ :right, :sec_type]
@@ -215,8 +221,11 @@ def essential
215221
end
216222

217223

218-
# creates a new Contract substituting attributes by the provied key-value pairs
224+
# creates a new Contract substituting attributes by the provied key-value pairs.
225+
#
226+
# con_id is resetted
219227
def merge **new_attributes
228+
self.con_id = 0
220229
self.class.new attributes.merge new_attributes
221230
end
222231

spec/contract_helper.rb

Lines changed: 18 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -19,41 +19,23 @@ def request_con_id contract: SAMPLE
1919

2020
end
2121

22-
shared_examples_for "correctly query's the tws" do
23-
24-
it "query_contract does not raise an error" do
25-
expect { contract.query_contract }.not_to raise_error
26-
end
27-
28-
29-
it "query_contract resets con_id" do
30-
query_contract = contract.query_contract
31-
unless contract.sec_type.nil?
32-
expect( contract.con_id ).to be_zero
33-
end
34-
end
35-
it "verify does intitialize con_id and contract_detail " do
36-
contract.verify do | c |
37-
expect( c.con_id ).not_to be_zero
38-
expect( c.contract_detail).to be_a IB::ContractDetail
39-
end
40-
end
41-
42-
it "verify returns a number" do
43-
expect( contract.verify ).to be > 0
44-
end
45-
46-
22+
RSpec.shared_examples 'a complete Contract Object' do
23+
subject{ the_contract }
24+
it_behaves_like 'a valid Contract Object'
25+
it { is_expected.to be_an IB::Contract }
26+
its( :contract_detail ){ is_expected.to be_a IB::ContractDetail }
27+
its( :primary_exchange){ is_expected.to be_a String }
4728
end
48-
shared_examples_for "invalid query of tws" do
49-
50-
it "does not verify " do
51-
contract.verify
52-
expect( should_log /Not a valid Contract/ ).to be_truthy
53-
end
54-
55-
it "returns zero" do
56-
expect( contract.verify ).to be_zero
57-
end
58-
29+
RSpec.shared_examples 'a valid Contract Object' do
30+
subject{ the_contract }
31+
it { is_expected.to be_an IB::Contract }
32+
its( :con_id ){ is_expected.to be_empty.or be_a(Numeric) }
33+
its( :contract_detail ){ is_expected.to be_nil.or be_a(IB::ContractDetail) }
34+
its( :symbol ){ is_expected.to be_a String }
35+
its( :local_symbol ){ is_expected.to be_a String }
36+
its( :currency ){ is_expected.to be_a String }
37+
its( :sec_type ){ is_expected.to be_a(Symbol).and satisfy { |sec_type| IB::SECURITY_TYPES.values.include?(sec_type) } }
38+
its( :trading_class ){ is_expected.to be_a String }
39+
its( :exchange ){ is_expected.to be_a String }
40+
its( :primary_exchange){ is_expected.to be_nil.or be_a(String) }
5941
end
Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
require 'main_helper'
2+
require 'contract_helper' # provides request_con_id
3+
4+
RSpec.shared_examples 'ContractData Message' do
5+
subject{ the_message }
6+
it { is_expected.to be_an IB::Messages::Incoming::ContractData }
7+
its( :contract ){ is_expected.to be_a IB::Contract }
8+
its( :contract_details ){ is_expected.to be_a IB::ContractDetail }
9+
its( :message_id ){ is_expected.to eq 10 }
10+
its( :version ){ is_expected.to eq 8 }
11+
its( :buffer ){ is_expected.to be_empty }
12+
it 'has class accessors as well' do
13+
expect( subject.class.message_id).to eq 10
14+
expect( subject.class.message_type).to eq :ContractData
15+
end
16+
end
17+
18+
RSpec.describe IB::Messages::Incoming::ContractData do
19+
20+
# uses the SAMPLE Contract specified in spec_helper
21+
22+
context IB::Stock, :connected => true do
23+
before(:all) do
24+
establish_connection
25+
request_con_id # populate the recieved array with Contract and ContractDetail Message
26+
end
27+
28+
after(:all) { close_connection }
29+
30+
it_behaves_like 'ContractData Message' do
31+
let( :the_message ){ IB::Connection.current.received[:ContractData].first }
32+
end
33+
34+
35+
it_behaves_like 'a complete Contract Object' do
36+
let( :the_contract ){ IB::Connection.current.received[:ContractData].first.contract }
37+
end
38+
# it "inspects" do # debugging
39+
# ib = IB::Connection.current
40+
# contract = ib.received[:ContractData].contract.first
41+
# contract_details = ib.received[:ContractData].contract_details.first
42+
#
43+
# puts contract.inspect
44+
# puts contract_details.inspect
45+
# end
46+
47+
end
48+
end # describe IB::Messages:Incoming
49+

spec/model/ib/contract_spec.rb

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
require 'main_helper'
2+
require 'contract_helper' # provides request_con_id
3+
4+
RSpec.shared_examples 'ContractData Message' do
5+
subject{ the_message }
6+
it { is_expected.to be_an IB::Messages::Incoming::ContractData }
7+
its( :contract ){ is_expected.to be_a IB::Contract }
8+
its( :contract_details ){ is_expected.to be_a IB::ContractDetail }
9+
its( :message_id ){ is_expected.to eq 10 }
10+
its( :version ){ is_expected.to eq 8 }
11+
its( :buffer ){ is_expected.to be_empty }
12+
it 'has class accessors as well' do
13+
expect( subject.class.message_id).to eq 10
14+
expect( subject.class.message_type).to eq :ContractData
15+
end
16+
end
17+
18+
RSpec.describe IB::Contract do
19+
20+
# uses the SAMPLE Contract specified in spec_helper
21+
22+
context IB::Stock, :connected => true do
23+
before(:all) do
24+
establish_connection
25+
request_con_id # populate the recieved array with Contract and ContractDetail Message
26+
end
27+
28+
after(:all) { close_connection }
29+
30+
31+
it_behaves_like 'a valid Contract Object' do
32+
let( :the_contract ){ SAMPLE }
33+
end
34+
35+
36+
context '#merge' do
37+
subject{ SAMPLE.merge( symbol: 'GE' ) } # returns a new object
38+
its( :object_id ){is_expected.not_to eq SAMPLE.object_id }
39+
its( :symbol ){is_expected.to eq 'GE'}
40+
its( :con_id ){is_expected.to be_zero}
41+
end
42+
43+
44+
45+
46+
end
47+
end # describe IB::Messages:Incoming
48+

0 commit comments

Comments
 (0)