orders 0.0.2 → 0.0.3
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/HISTORY +4 -0
- data/README.rdoc +1 -1
- data/VERSION +1 -1
- data/lib/orders/indexed_list.rb +11 -2
- data/lib/orders/order_book.rb +2 -0
- data/lib/orders/order_list.rb +10 -1
- data/spec/orders/indexed_list_spec.rb +1 -0
- data/spec/orders/order_book_spec.rb +18 -2
- data/spec/orders/order_list_spec.rb +144 -49
- data/spec/orders/shared_examples.rb +103 -27
- metadata +1 -1
data/HISTORY
CHANGED
data/README.rdoc
CHANGED
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
0.0.
|
1
|
+
0.0.3
|
data/lib/orders/indexed_list.rb
CHANGED
@@ -22,9 +22,18 @@ module Orders
|
|
22
22
|
self
|
23
23
|
end
|
24
24
|
|
25
|
-
#
|
25
|
+
# Removes item with given index from the list
|
26
|
+
def delete_by_index index
|
27
|
+
remove self[index] if self[index]
|
28
|
+
end
|
29
|
+
|
30
|
+
# Removes either all items, or items for which given block returns trueish value
|
26
31
|
def clear
|
27
|
-
|
32
|
+
if block_given?
|
33
|
+
each {|item| remove item if yield item}
|
34
|
+
else
|
35
|
+
each_value { |item| remove item }
|
36
|
+
end
|
28
37
|
end
|
29
38
|
|
30
39
|
# Yields list items in order of their index
|
data/lib/orders/order_book.rb
CHANGED
@@ -18,6 +18,7 @@ module Orders
|
|
18
18
|
def add item
|
19
19
|
if item.price > 0
|
20
20
|
@changed = true # Marking DOM as changed
|
21
|
+
item.order_book = self
|
21
22
|
super
|
22
23
|
else
|
23
24
|
self
|
@@ -27,6 +28,7 @@ module Orders
|
|
27
28
|
# Does not call super!
|
28
29
|
def remove item
|
29
30
|
@changed = true if delete index item # Marking DOM as changed
|
31
|
+
item.order_book = nil
|
30
32
|
self
|
31
33
|
end
|
32
34
|
end
|
data/lib/orders/order_list.rb
CHANGED
@@ -16,8 +16,17 @@ module Orders
|
|
16
16
|
end
|
17
17
|
|
18
18
|
def add item
|
19
|
-
@order_books[item.isin_id] ||= Orders::OrderBook.new
|
19
|
+
order_book = @order_books[item.isin_id] ||= Orders::OrderBook.new(item.isin_id)
|
20
|
+
old_item = self[index item]
|
21
|
+
remove old_item if old_item # Remove old item with the same index(id)
|
22
|
+
order_book.add item # Add item to appropriate order book
|
20
23
|
super
|
21
24
|
end
|
25
|
+
|
26
|
+
def remove item
|
27
|
+
# Removing item from appropriate order book when it's deleted from order list
|
28
|
+
@order_books[item.isin_id].remove item if delete index item
|
29
|
+
self
|
30
|
+
end
|
22
31
|
end
|
23
32
|
end
|
@@ -7,8 +7,9 @@ describe Orders::OrderBook do
|
|
7
7
|
|
8
8
|
before(:each) do
|
9
9
|
@item = Orders::OrderBookItem.new :id => 0, :price => 20
|
10
|
-
@item1 = Orders::OrderBookItem.new :id => 1, :price =>
|
11
|
-
@
|
10
|
+
@item1 = Orders::OrderBookItem.new :id => 1, :price => 15
|
11
|
+
@item2 = Orders::OrderBookItem.new :id => 2, :price => 10
|
12
|
+
@zero_price_item = Orders::OrderBookItem.new :id => 3, :price => 0
|
12
13
|
end
|
13
14
|
|
14
15
|
it_behaves_like 'index_list'
|
@@ -37,6 +38,12 @@ describe Orders::OrderBook do
|
|
37
38
|
subject.add(@zero_price_item)
|
38
39
|
subject.changed.should == false
|
39
40
|
end
|
41
|
+
|
42
|
+
it 'does not set item`s order_book property' do
|
43
|
+
subject.remove(@zero_price_item)
|
44
|
+
@zero_price_item.order_book.should == nil
|
45
|
+
end
|
46
|
+
|
40
47
|
end
|
41
48
|
|
42
49
|
it 'sets changed status to true if item was added' do
|
@@ -44,6 +51,10 @@ describe Orders::OrderBook do
|
|
44
51
|
subject.changed.should == true
|
45
52
|
end
|
46
53
|
|
54
|
+
it 'sets added item`s order_book property' do
|
55
|
+
subject.add(@item1)
|
56
|
+
@item1.order_book.should == subject
|
57
|
+
end
|
47
58
|
end
|
48
59
|
|
49
60
|
describe 'removing item' do
|
@@ -57,6 +68,11 @@ describe Orders::OrderBook do
|
|
57
68
|
subject.changed.should == true
|
58
69
|
end
|
59
70
|
|
71
|
+
it 'unsets removed item`s order_book property' do
|
72
|
+
subject.remove(@item)
|
73
|
+
@item.order_book.should == nil
|
74
|
+
end
|
75
|
+
|
60
76
|
context 'that is not in list' do
|
61
77
|
|
62
78
|
it 'returns self' do
|
@@ -2,16 +2,61 @@ require 'spec_helper'
|
|
2
2
|
require 'spec_helper'
|
3
3
|
require 'orders/shared_examples.rb'
|
4
4
|
|
5
|
-
|
5
|
+
shared_examples_for 'adding_item_to_order_books' do
|
6
|
+
it_behaves_like 'creating_order_books'
|
7
|
+
|
8
|
+
it 'adds this item to appropriate order book' do
|
9
|
+
subject.add new_item
|
10
|
+
order_book = subject.order_books[new_item.isin_id]
|
11
|
+
order_book.should have_key new_item.price
|
12
|
+
order_book[new_item.price].should == new_item
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
shared_examples_for 'not_adding_item_to_order_books' do
|
17
|
+
it_behaves_like 'creating_order_books'
|
18
|
+
|
19
|
+
it 'does not add this item to order list' do
|
20
|
+
subject.add new_item
|
21
|
+
order_book = subject.order_books[new_item.isin_id]
|
22
|
+
order_book.should_not have_key new_item.price
|
23
|
+
order_book[new_item.price].should == nil
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
shared_examples_for 'creating_order_books' do
|
28
|
+
it 'creates appropriate order book' do
|
29
|
+
subject.add(new_item)
|
30
|
+
subject.order_books.should have(expected_number_of_books).books
|
31
|
+
order_book = subject.order_books[new_item.isin_id]
|
32
|
+
order_book.should be_an Orders::OrderBook
|
33
|
+
order_book.isin_id.should == new_item.isin_id
|
34
|
+
end
|
35
|
+
|
36
|
+
it 'sets item`s order_book property correctly' do
|
37
|
+
subject.add(new_item)
|
38
|
+
if new_item.price == 0
|
39
|
+
new_item.order_book.should == nil
|
40
|
+
else
|
41
|
+
order_book = subject.order_books[new_item.isin_id]
|
42
|
+
new_item.order_book.should == order_book
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
6
47
|
describe Orders::OrderList do
|
7
48
|
subject { Orders::OrderList.new }
|
8
49
|
let(:item_index) { @item.id }
|
9
50
|
|
10
51
|
before(:each) do
|
11
|
-
@item = Orders::OrderBookItem.new :id => 0, :price => 20
|
12
|
-
@item1 = Orders::OrderBookItem.new :id => 1, :price => 10
|
13
|
-
@
|
14
|
-
@
|
52
|
+
@item = Orders::OrderBookItem.new :isin_id => 1234, :id => 0, :price => 20
|
53
|
+
@item1 = Orders::OrderBookItem.new :isin_id => 1234, :id => 1, :price => 10
|
54
|
+
@same_isin_item = @item1
|
55
|
+
@item2 = Orders::OrderBookItem.new :isin_id => 5678, :id => 2, :price => 10
|
56
|
+
@diff_isin_item = @item2
|
57
|
+
@zero_price_item = Orders::OrderBookItem.new :isin_id => 1234, :id => 3, :price => 0
|
58
|
+
@repeat_item = Orders::OrderBookItem.new :isin_id => 1234, :id => 0, :price => 13
|
59
|
+
@repeat_zero_price_item = Orders::OrderBookItem.new :isin_id => 1234, :id => 0, :price => 0
|
15
60
|
end
|
16
61
|
|
17
62
|
it_behaves_like 'index_list'
|
@@ -19,38 +64,75 @@ describe Orders::OrderList do
|
|
19
64
|
specify { subject.order_books.should be_empty }
|
20
65
|
|
21
66
|
describe 'adding item' do
|
67
|
+
let(:expected_number_of_books) { 1 }
|
68
|
+
|
22
69
|
context 'to empty OrderList' do
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
subject.order_books[@item.isin_id].should be_an Orders::OrderBook
|
27
|
-
subject.order_books.should have(1).book
|
28
|
-
end
|
70
|
+
let(:new_item) { @item }
|
71
|
+
|
72
|
+
it_behaves_like 'adding_item_to_order_books'
|
29
73
|
|
74
|
+
context 'with zero price' do
|
75
|
+
let(:new_item) { @zero_price_item }
|
76
|
+
|
77
|
+
it_behaves_like 'not_adding_item_to_order_books'
|
78
|
+
end
|
30
79
|
end
|
31
80
|
|
32
81
|
context 'to non-empty OrderList' do
|
33
82
|
before(:each) do
|
34
83
|
subject.add(@item).size.should == 1
|
35
84
|
end
|
85
|
+
|
86
|
+
context 'with existing isin' do
|
87
|
+
let(:new_item) { @same_isin_item }
|
88
|
+
|
89
|
+
it_behaves_like 'adding_item_to_order_books'
|
90
|
+
end
|
91
|
+
|
92
|
+
context 'with different isin' do
|
93
|
+
let(:new_item) { @diff_isin_item }
|
94
|
+
let(:expected_number_of_books) { 2 }
|
95
|
+
|
96
|
+
it_behaves_like 'adding_item_to_order_books'
|
97
|
+
end
|
98
|
+
|
99
|
+
context 'with zero price' do
|
100
|
+
let(:new_item) { @zero_price_item }
|
101
|
+
|
102
|
+
it_behaves_like 'not_adding_item_to_order_books'
|
103
|
+
end
|
104
|
+
|
105
|
+
context 'with repeat isin/id and non-zero price' do
|
106
|
+
let(:new_item) { @repeat_item }
|
107
|
+
|
108
|
+
it_behaves_like 'adding_item_to_order_books'
|
109
|
+
|
110
|
+
it 'changes price of item in list' do
|
111
|
+
subject.add new_item
|
112
|
+
subject[item_index].price.should_not == @item.price
|
113
|
+
subject[item_index].price.should == @repeat_item.price
|
114
|
+
end
|
115
|
+
|
116
|
+
it 'removes old item from appropriate order book' do
|
117
|
+
subject.add new_item
|
118
|
+
order_book = subject.order_books[@item.isin_id]
|
119
|
+
order_book.should_not have_key @item.price
|
120
|
+
end
|
121
|
+
end
|
122
|
+
|
123
|
+
context 'with repeat isin/id and zero price' do
|
124
|
+
let(:new_item) { @repeat_zero_price_item }
|
125
|
+
|
126
|
+
it_behaves_like 'not_adding_item_to_order_books'
|
127
|
+
|
128
|
+
it 'removes old item from appropriate order book' do
|
129
|
+
subject.add new_item
|
130
|
+
order_book = subject.order_books[@item.isin_id]
|
131
|
+
order_book.should_not have_key @item.price
|
132
|
+
end
|
133
|
+
end
|
36
134
|
end
|
37
|
-
|
38
|
-
# it 'returns self' do
|
39
|
-
# subject.add(@zero_price_item).should == subject
|
40
|
-
# end
|
41
|
-
#
|
42
|
-
# it 'does not add such item to the list' do
|
43
|
-
# subject.add(@zero_price_item)
|
44
|
-
# subject[subject.index @zero_price_item].should == nil
|
45
|
-
# subject.size.should == 1
|
46
|
-
# end
|
47
|
-
#
|
48
|
-
# it 'does not set changed status to true' do
|
49
|
-
# subject.add(@zero_price_item)
|
50
|
-
# subject.changed.should == false
|
51
|
-
# end
|
52
|
-
# end
|
53
|
-
#
|
135
|
+
|
54
136
|
it 'sets changed status to true if item was added' do
|
55
137
|
subject.add(@item1)
|
56
138
|
end
|
@@ -58,27 +140,40 @@ describe Orders::OrderList do
|
|
58
140
|
end
|
59
141
|
|
60
142
|
describe 'removing item' do
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
143
|
+
before(:each) do
|
144
|
+
subject.add(@item).size.should == 1
|
145
|
+
end
|
146
|
+
|
147
|
+
context 'with existing item' do
|
148
|
+
let(:unwanted_item) { @item }
|
149
|
+
let(:expected_size) { 0 }
|
150
|
+
|
151
|
+
it 'deletes item from the list' do
|
152
|
+
subject.remove(unwanted_item)
|
153
|
+
subject[unwanted_item.id].should == nil
|
154
|
+
subject.size.should == expected_size
|
155
|
+
end
|
156
|
+
|
157
|
+
it 'removes item from its related order book' do
|
158
|
+
subject.remove(unwanted_item)
|
159
|
+
subject.order_books[unwanted_item.isin_id].should_not have_key unwanted_item.price
|
160
|
+
end
|
161
|
+
end
|
162
|
+
|
163
|
+
context 'with non-existing item' do
|
164
|
+
let(:unwanted_item) { @item1 }
|
165
|
+
let(:expected_size) { 1 }
|
166
|
+
|
167
|
+
it 'still returns the list itself' do
|
168
|
+
subject.remove(unwanted_item).should == subject
|
169
|
+
end
|
170
|
+
|
171
|
+
it 'deletes nothing from the list' do
|
172
|
+
subject.remove(unwanted_item)
|
173
|
+
subject[@item.id].should == @item
|
174
|
+
subject.size.should == expected_size
|
175
|
+
end
|
176
|
+
end
|
82
177
|
end
|
83
178
|
end
|
84
179
|
|
@@ -43,29 +43,112 @@ shared_examples_for 'index_list' do
|
|
43
43
|
describe '#remove' do
|
44
44
|
before(:each) { subject.add(@item).add(@item1).size.should == 2 }
|
45
45
|
|
46
|
-
|
47
|
-
|
46
|
+
context 'removing existing item' do
|
47
|
+
it 'returns self for easy method chaining' do
|
48
|
+
subject.remove(@item).should == subject
|
49
|
+
end
|
50
|
+
|
51
|
+
it 'removes item from indexed list' do
|
52
|
+
subject.remove(@item)
|
53
|
+
subject.values.should_not include @item
|
54
|
+
subject[item_index].should == nil
|
55
|
+
end
|
56
|
+
|
57
|
+
it 'does not remove other items' do
|
58
|
+
subject.remove(@item)
|
59
|
+
subject.values.should include @item1
|
60
|
+
subject.size.should == 1
|
61
|
+
end
|
48
62
|
end
|
49
63
|
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
64
|
+
context 'deleting non-existing items by index' do
|
65
|
+
it 'still returns self' do
|
66
|
+
subject.remove(@item2).should == subject
|
67
|
+
end
|
68
|
+
|
69
|
+
it 'removes nothing from the list' do
|
70
|
+
subject.remove(@item2)
|
71
|
+
subject.values.should include @item, @item1
|
72
|
+
subject.size.should == 2
|
73
|
+
end
|
74
|
+
end
|
75
|
+
end
|
76
|
+
|
77
|
+
describe '#delete_by_index' do
|
78
|
+
before(:each) { subject.add(@item).add(@item1) }
|
79
|
+
context 'deleting existing item by index' do
|
80
|
+
|
81
|
+
it 'returns self' do
|
82
|
+
subject.delete_by_index(item_index).should == subject
|
83
|
+
end
|
84
|
+
|
85
|
+
it 'deletes item with given index from the list' do
|
86
|
+
subject.delete_by_index(item_index)
|
87
|
+
subject.values.should_not include @item
|
88
|
+
subject[item_index].should == nil
|
89
|
+
end
|
90
|
+
|
91
|
+
it 'calls #remove on this item to properly remove it' do
|
92
|
+
subject.should_receive(:remove).with(@item)
|
93
|
+
subject.delete_by_index(item_index)
|
94
|
+
end
|
95
|
+
|
96
|
+
it 'does not remove other items' do
|
97
|
+
subject.delete_by_index(item_index)
|
98
|
+
subject.values.should include @item1
|
99
|
+
subject.size.should == 1
|
100
|
+
end
|
101
|
+
end
|
102
|
+
|
103
|
+
context 'deleting non-existing items by index' do
|
104
|
+
it 'returns nil' do
|
105
|
+
subject.delete_by_index(subject.index @item2).should == nil
|
106
|
+
end
|
107
|
+
|
108
|
+
it 'removes nothing from the list' do
|
109
|
+
subject.delete_by_index(subject.index @item2)
|
110
|
+
subject.values.should include @item, @item1
|
111
|
+
subject.size.should == 2
|
112
|
+
end
|
55
113
|
end
|
56
114
|
end
|
57
115
|
|
58
116
|
describe '#clear' do
|
59
117
|
before(:each) { subject.add(@item).add(@item1) }
|
60
118
|
|
61
|
-
|
62
|
-
|
63
|
-
|
119
|
+
context 'without block' do
|
120
|
+
it 'removes all items from list' do
|
121
|
+
subject.clear
|
122
|
+
subject.should be_empty
|
123
|
+
end
|
124
|
+
|
125
|
+
it 'ensures that #remove method is called once for each item in list' do
|
126
|
+
subject.should_receive(:remove).twice
|
127
|
+
subject.clear
|
128
|
+
end
|
64
129
|
end
|
65
130
|
|
66
|
-
|
67
|
-
|
68
|
-
|
131
|
+
context 'with block given' do
|
132
|
+
it 'yields items from list in index order' do
|
133
|
+
@count = 0
|
134
|
+
@items = []
|
135
|
+
subject.clear do |item|
|
136
|
+
@count += 1
|
137
|
+
@items << item
|
138
|
+
end
|
139
|
+
@count.should == 2
|
140
|
+
if subject.index(@item) < subject.index(@item1)
|
141
|
+
@items.should == [@item, @item1]
|
142
|
+
else
|
143
|
+
@items.should == [@item1, @item]
|
144
|
+
end
|
145
|
+
end
|
146
|
+
|
147
|
+
it 'only removes items for which given block returns true' do
|
148
|
+
subject.should_receive(:remove).once
|
149
|
+
subject.clear { |item| true if item == @item1 }
|
150
|
+
subject.should have_key item_index
|
151
|
+
end
|
69
152
|
end
|
70
153
|
end
|
71
154
|
|
@@ -74,24 +157,17 @@ shared_examples_for 'index_list' do
|
|
74
157
|
|
75
158
|
it 'yields items from list in index order' do
|
76
159
|
@count = 0
|
160
|
+
@items = []
|
77
161
|
subject.each do |item|
|
78
162
|
@count += 1
|
79
|
-
|
80
|
-
when 1
|
81
|
-
if subject.index(@item) < subject.index(@item1)
|
82
|
-
item.should == @item
|
83
|
-
else
|
84
|
-
item.should == @item1
|
85
|
-
end
|
86
|
-
when 2
|
87
|
-
if subject.index(@item) < subject.index(@item1)
|
88
|
-
item.should == @item1
|
89
|
-
else
|
90
|
-
item.should == @item
|
91
|
-
end
|
92
|
-
end
|
163
|
+
@items << item
|
93
164
|
end
|
94
165
|
@count.should == 2
|
166
|
+
if subject.index(@item) < subject.index(@item1)
|
167
|
+
@items.should == [@item, @item1]
|
168
|
+
else
|
169
|
+
@items.should == [@item1, @item]
|
170
|
+
end
|
95
171
|
end
|
96
172
|
|
97
173
|
it 'returns list item in array, sorted by their index, if no block given' do
|