orders 0.0.2 → 0.0.3
Sign up to get free protection for your applications and to get access to all the features.
- 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
|